#!/usr/bin/ruby
# Copyright (c) 2008-2009 Takaaki Kasai
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

require 'gtk2'

$re_float = /[-+]?(?:[0-9]+(?:\.[0-9]*)?|(?:\.[0-9]+))(?:[eE][-+]?[0-9]+)?/
#$child_pids = []

# ファイル選択ボタン
# Buttonのサブクラス
class FileChooserButton2 < Gtk::Button #{{{
	# ファイル選択ボタン生成
	# コールバックプロシージャにファイルパスを渡す
	# ボタンオブジェクトを返す

	def current_folder=(folder)
		if File.directory?(folder) then
			@current_folder = File.expand_path(folder)
		end
	end

	# コールバックプロシージャをセットする
	# これをしないと何も起こらない
	def set_callback(callback)
		@callback = callback
	end

	# action : 動作指定 : OPEN,SAVE
	# label : ボタンに表示するラベル
	# title : ダイアログウィンドウのタイトル
	def initialize(action="OPEN",label=nil,title=nil) #{{{
		@callback = Proc.new{}
		@current_folder = nil
		label = "参照..." unless label
		super(label)
		case action
		when "OPEN"
			title = "Open File" unless title
			@dialog = Gtk::FileChooserDialog.new(
												 title,nil,Gtk::FileChooser::ACTION_OPEN,nil,
												 [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
												 [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
		when "SAVE"
			title = "Save File" unless title
			@dialog = Gtk::FileChooserDialog.new(
												 title,nil,Gtk::FileChooser::ACTION_SAVE,nil,
												 [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
												 [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
		end
		self.signal_connect("clicked") do
			@dialog.current_folder = @current_folder if @current_folder
			@dialog.default_response = Gtk::Dialog::RESPONSE_ACCEPT
			if @dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
				#puts "filename = #{@dialog.filename}"
				@callback.call(@dialog.filename)
			end
			@dialog.hide
		end
	end #}}}

	attr_accessor :dialog

end #}}}

# プロット系列データクラス
# VBoxのサブクラス
class PlotSeries < Gtk::VBox #{{{
	@@counter = 0
	#def del_connect(&proc)
	#	@delete_button.signal_connect("clicked",&proc)
	#end
	# ボタンのsensitiveなどを更新
	def update_updown #{{{
		if parent.children[0] == self then
			@go_up_button.sensitive = false
		else
			@go_up_button.sensitive = true
		end
		if parent.children[parent.children.length-1] == self then
			@go_down_button.sensitive = false
		else
			@go_down_button.sensitive = true
		end
	end #}}}

	# 線色のメニューアイテムを生成
	def get_item_linecolor(colorname,r,g,b) #{{{
		item = Gtk::MenuItem.new
		style = Gtk::Style.new
		style.set_bg(Gtk::STATE_NORMAL,(r+1)*256-1,(g+1)*256-1,(b+1)*256-1)
		style.set_bg(Gtk::STATE_PRELIGHT,(r+1)*256-1,(g+1)*256-1,(b+1)*256-1)
		box = Gtk::EventBox.new()
		box.width_request = 30
		box.height_request = 15
		box.set_style(style)
		item.add(box)
		item.signal_connect("activate"){
			@linecolor = colorname
		}
		return item
	end
	#}}}

	# カラーネームまたはカラーコードをRGBに変換
	def convert_colorname_to_rgb(color_x) #{{{
		if color_x =~ /grey/ then
			color_x.gsub!(/grey/,"gray")
		end
		# カラー表(灰色はgreyを省略しgrayで統一）
		color_palette_table = [ #{{{
			["white"           , "#ffffff"],
			["black"           , "#000000"],
			["gray0"           , "#000000"],
			["gray10"          , "#1a1a1a"],
			["gray20"          , "#333333"],
			["gray30"          , "#4d4d4d"],
			["gray40"          , "#666666"],
			["gray50"          , "#7f7f7f"],
			["gray60"          , "#999999"],
			["gray70"          , "#b3b3b3"],
			["gray80"          , "#cccccc"],
			["gray90"          , "#e5e5e5"],
			["gray100"         , "#ffffff"],
			["gray"            , "#bebebe"],
			["light-gray"      , "#d3d3d3"],
			["dark-gray"       , "#a9a9a9"],
			["red"             , "#ff0000"],
			["light-red"       , "#f03232"],
			["dark-red"        , "#8b0000"],
			["yellow"          , "#ffff00"],
			["light-yellow"    , "#ffffe0"],
			["dark-yellow"     , "#c8c800"],
			["green"           , "#00ff00"],
			["light-green"     , "#90ee90"],
			["dark-green"      , "#006400"],
			["spring-green"    , "#00ff7f"],
			["forest-green"    , "#228b22"],
			["sea-green"       , "#2e8b57"],
			["blue"            , "#0000ff"],
			["light-blue"      , "#add8e6"],
			["dark-blue"       , "#00008b"],
			["midnight-blue"   , "#191970"],
			["navy"            , "#000080"],
			["medium-blue"     , "#0000cd"],
			["royalblue"       , "#4169e1"],
			["skyblue"         , "#87ceeb"],
			["cyan"            , "#00ffff"],
			["light-cyan"      , "#e0ffff"],
			["dark-cyan"       , "#008b8b"],
			["magenta"         , "#ff00ff"],
			["light-magenta"   , "#f055f0"],
			["dark-magenta"    , "#8b008b"],
			["turquoise"       , "#40e0d0"],
			["light-turquoise" , "#afeeee"],
			["dark-turquoise"  , "#00ced1"],
			["pink"            , "#ffc0cb"],
			["light-pink"      , "#ffb6c1"],
			["dark-pink"       , "#ff1493"],
			["coral"           , "#ff7f50"],
			["light-coral"     , "#f08080"],
			["orange-red"      , "#ff4500"],
			["salmon"          , "#fa8072"],
			["light-salmon"    , "#ffa07a"],
			["dark-salmon"     , "#e9967a"],
			["aquamarine"      , "#7fffd4"],
			["khaki"           , "#f0e68c"],
			["dark-khaki"      , "#bdb76b"],
			["goldenrod"       , "#daa520"],
			["light-goldenrod" , "#eedd82"],
			["dark-goldenrod"  , "#b8860b"],
			["gold"            , "#ffd700"],
			["beige"           , "#f5f5dc"],
			["brown"           , "#a52a2a"],
			["orange"          , "#ffa500"],
			["dark-orange"     , "#ff8c00"],
			["violet"          , "#ee82ee"],
			["dark-violet"     , "#9400d3"],
			["plum"            , "#dda0dd"],
			["purple"          , "#a020f0"],
		]
		#}}}
		#color_x.gsub!(/grey/,"gray")
		if e = color_palette_table.assoc(color_x) then
			colorname = e[0]
			colorcode = e[1]
		elsif e = color_palette_table.rassoc(color_x) then
			colorname = e[0]
			colorcode = e[1]
		elsif color_x =~ /^(\#[0-9A-Za-z]{6})$/ then
			colorname = $1
			colorcode = $1
		else
			return nil
		end
		colorcode =~ /\#([0-9A-Za-z]{2})([0-9A-Za-z]{2})([0-9A-Za-z]{2})/
		r = $1.hex
		g = $2.hex
		b = $3.hex
		return [colorname,r,g,b]
	end
	#}}}

	# 線色の選択を更新
	def update_linecolor #{{{
		# メニューの選択を現在の色に合わせる。メニューになければアイテム追加
		if e = @linecolor_menu_contents.assoc(@linecolor) then
			@opt_linecolor.history = @linecolor_menu_contents.index(e)
		elsif rgb = convert_colorname_to_rgb(@linecolor) then
			@linecolor = rgb[0]
			if e = @linecolor_menu_contents.assoc(@linecolor) then
				@opt_linecolor.history = @linecolor_menu_contents.index(e)
			else
				@linecolor_menu_contents << [] # セパレータのための順番合わせ
				@linecolor_menu_contents << rgb.flatten
				@opt_linecolor.menu.append(Gtk::SeparatorMenuItem.new)
				@opt_linecolor.menu.append(get_item_linecolor(@linecolor,rgb[1],rgb[2],rgb[3]))
				@opt_linecolor.show_all
				e = @linecolor_menu_contents.assoc(@linecolor)
				@opt_linecolor.history = @linecolor_menu_contents.index(e)
			end
		else
			# 想定外の色だった場合色選択を無効にする
			#p "linecolor is not included."
			@opt_linecolor.sensitive = false
		end
	end #}}}

	# ポイント種類の選択を更新
	def update_pointtype #{{{
		@opt_pointtype.history = @pointtype_order.index(@pointtype)
	end #}}}

	# デフォルト値セット
	def set_defaults(sw=nil) #{{{
		@datafile  = ""
		@x_row     = 1
		@y_row     = 2
		@x_expr   = "x*1e0"
		@y_expr   = "y*1e0"
		@linestyle = "linespoints"
		@linetype  = 1
		@linewidth = 3
		@linecolor_menu_contents = [
			[ "red"            , 255 , 0   , 0   ] , 
			[ "blue"           , 0   , 0   , 255 ] , 
			[ "dark-green"     , 0   , 100 , 0   ] , 
			[ "dark-magenta"   , 139 , 0   , 139 ] , 
			[ "dark-cyan"      , 0   , 139 , 139 ] , 
			[ "coral"          , 255 , 127 , 80  ] , 
			[ "dark-pink"      , 255 , 20  , 147 ] , 
			[ "brown"          , 165 , 42  , 42  ] , 
			[ "dark-turquoise" , 0   , 206 , 209 ] , 
			[ "orange-red"     , 255 , 69  , 0   ] , 
			[ "goldenrod"      , 218 , 165 , 32  ] , 
			[ "black"          , 0   , 0   , 0   ] , 
			[ "gray30"         , 77  , 77  , 77  ] , 
			[ "gray40"         , 102 , 102 , 102 ] , 
			[ "gray50"         , 127 , 127 , 127 ] , 
			[ "gray60"         , 153 , 153 , 153 ] , 
			[ "gray70"         , 179 , 179 , 179 ] , 
			[ "gray80"         , 204 , 204 , 204 ] , 
			#[ "white"          , 255 , 255 , 255 ] , 
		]
		@linecolor_order = [
			"red","blue","dark-green","dark-magenta", "dark-cyan", "coral",
			"dark-pink", "brown", "dark-turquoise", "orange-red", "goldenrod",
			"black","#444444","#666666","#888888","#aaaaaa","#cccccc",
		]
		@linecolor = @linecolor_order[@@counter%11]
		@pointtype_order = [ 12, 6, 4, 8, 10, 13, 7, 5, 9, 11, 1,]
		@pointtype = @pointtype_order[@@counter%11]
		@title     = "plot-title"
		@y2axis    = false
		case sw
		when "first"
			@removable = false
		else
			@removable = true
		end
	end #}}}
	attr_accessor :linecolor_order, :pointtype_order
	attr_reader :datafile, :x_row, :y_row, :x_expr, :y_expr,
		:linestyle, :linetype, :linewidth, :linecolor,
		:pointtype, :title, :y2axis

	# インスタンス変数セットメソッド群{{{
	# datafileセット関数
	def datafile=(val)
		@datafile = val
		@datafile_select_button.label = File.basename(@datafile)
		@datafile_entry.text = @datafile
		@datafile_entry.position = -1
	end

	# x_rowセット関数
	def x_row=(val)
		@x_row = val
		@adj_x_row.value = @x_row
	end

	# y_rowセット関数
	def y_row=(val)
		@y_row = val
		@adj_y_row.value = @y_row
	end

	# x_exprセット関数
	def x_expr=(val)
		@x_expr = val
		@entry_x_expr.text = @x_expr
	end

	# y_exprセット関数
	def y_expr=(val)
		@y_expr = val
		@entry_y_expr.text = @y_expr
	end

	# linestyleセット関数
	def linestyle=(ls)
		@linestyle = ls
		case @linestyle
		when "lines"
			@opt_style.history = 0
		when "linespoints"
			@opt_style.history = 1
		when "points"
			@opt_style.history = 2
		end
	end

	# linetypeセット関数
	def linetype=(val)
		@linetype = val
		@opt_linetype.history = val - 1
	end

	# linewidthセット関数
	def linewidth=(val)
		@linewidth = val
		@adj_linewidth.value = @linewidth
	end

	# linecolorセット関数
	def linecolor=(val)
		@linecolor = val
		update_linecolor()
	end

	# pointtypeセット関数
	def pointtype=(val)
		@pointtype = val
		update_pointtype()
	end

	# titleセット関数
	def title=(val)
		@title = val
		@entry_title.text = @title
	end

	# y2axisセット関数
	def y2axis=(val)
		@y2axis = val
		@check_y2axis.active = @y2axis
	end

	# インスタンス変数セットメソッド群ここまで}}}

	# 初期化関数
	def initialize(option,parent,sw=nil) #{{{
		@option = option
		#delete_button = Gtk::Button.new("削除")
		#p parent
		super(false,0)
		set_defaults(sw)
		@@counter += 1

		# コンテンツボックス
		vbox_contents = Gtk::VBox.new(false,5)
		self.pack_start(vbox_contents,false,false,0)
		hbox_contents = Gtk::HBox.new(false,5)
		vbox_contents.pack_start(hbox_contents,false,false,0)

		# 情報格納ボックス
		vbox_info = Gtk::VBox.new(false,0)
		hbox_contents.pack_start(vbox_info,false,false,0)

		# Xデータ列、Yデータ列をあらかじめ定義(データファイル変更時に連動させるため)
		@adj_x_row = Gtk::Adjustment.new(1, 1, 100, 1, 1, 0)
		@adj_y_row = Gtk::Adjustment.new(1, 1, 100, 1, 1, 0)

		# 0列目
		hbox0 = Gtk::HBox.new(false,0)
		vbox_info.pack_start(hbox0,false,false,0)
		# データファイル選択 {{{
		@datafile_select_button = Gtk::Button.new("未選択",false)
		datafile_label = Gtk::Label.new("データファイル: ")
		@datafile_entry = Gtk::Entry.new
		@datafile_entry.editable = false
		@datafile_entry.sensitive = false
		hbox0.pack_start(datafile_label,false,false,0)
		hbox0.pack_start(@datafile_select_button,false,false,0)
		#hbox0.pack_start(@datafile_entry,true,true,0)

		# ポップアップメニューを出す
		@datafile_select_button.signal_connect("event") do |w, e|
			if (Gdk::Event::BUTTON_PRESS == e.event_type)
				datafile_menu = Gtk::Menu.new
				#datafile_pattern = ["*.dat","*.csv","*.vcsv","*.tsv"]
				datafile_pattern = @option.plot_datapattern.split(/\s*(,|;)\s*/)
				datafile_pattern_withdir = datafile_pattern.collect{|pt|File.join(File.dirname(@option.ins_general.datafile),pt)}.join("\0")
				datafile_array = Dir.glob(datafile_pattern_withdir)
				datafile_array.unshift(@option.ins_general.datafile) if @option.ins_general.datafile != ""
				datafile_array.sort!.uniq!
				if datafile_array.length == 0 then
					datafile_item = Gtk::MenuItem.new("select datafile",false)
					datafile_menu.append(datafile_item)
				else
					radio_datafile_group = Gtk::RadioMenuItem.new("",false)
					datafile_array.each do |df|
						radio_datafile = Gtk::RadioMenuItem.new(radio_datafile_group,File.basename(df),false)
						if @datafile == File.expand_path(df) then
							radio_datafile.active = true
						else
							radio_datafile.signal_connect("activate") do
								if @option.plot_resetrow then
									@adj_x_row.value = 1
									@adj_y_row.value = 2
								end
							end
						end
						radio_datafile.signal_connect("activate") do
							@datafile = File.expand_path(df)
							@datafile_select_button.label = File.basename(df)
							@datafile_entry.text = @datafile
							@datafile_entry.position = -1
						end
						datafile_menu.append(radio_datafile)
					end
				end
				datafile_menu.show_all
				datafile_menu.popup(nil, nil, e.button, e.time)
				true   # このイベントの処理は完了したので true を返す
			else
				false
			end
		end

		# デフォルトデータファイルと連動
		@datafile_select_button.signal_connect("expose_event") do
				if @datafile == "" && @option.ins_general.datafile != "" then
					@datafile = @option.ins_general.datafile
					@datafile_select_button.label = File.basename(@datafile)
					@datafile_entry.text = @datafile
					@datafile_entry.position = -1
				end
				#puts "exposed"
		end
		#}}}

		# 1列目
		hbox1 = Gtk::HBox.new(false,0)
		vbox_info.pack_start(hbox1,false,false,0)

		# Xデータ列 {{{
		#@adj_x_row = Gtk::Adjustment.new(1, 1, 100, 1, 1, 0) # アジャストメントは前に定義を移動
		spinner_x_row = Gtk::SpinButton.new(@adj_x_row, 0.0, 0)
		spinner_x_row.wrap = false
		## デフォルト値セット
		spinner_x_row.value = @x_row
		spinner_x_row.width_request = 40
		hbox_x_row = Gtk::HBox.new(false,0)
		vbox_x_row = Gtk::VBox.new(false,0)
		#hbox1.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox1.pack_start(vbox_x_row,false,false,0)
		vbox_x_row.pack_start(Gtk::Label.new.set_markup("<small>X</small>"),false,false,0)
		vbox_x_row.pack_start(hbox_x_row,false,false,0)
		hbox_x_row.pack_start(Gtk::Label.new("x="),false,false,0)
		hbox_x_row.pack_start(spinner_x_row,false,false,0)
		hbox_x_row.pack_start(Gtk::Label.new("列目"),false,false,3)
		## xデータ列変更時
		spinner_x_row.signal_connect("value_changed") do |w|
				@x_row = w.value_as_int
				#p @x_row = w.value_as_int
		end
		#}}}

		# Yデータ列 {{{
		#@adj_y_row = Gtk::Adjustment.new(1, 1, 100, 1, 1, 0) # アジャストメントは前に定義を移動
		spinner_y_row = Gtk::SpinButton.new(@adj_y_row, 0.0, 0)
		spinner_y_row.wrap = false
		## デフォルト値セット
		spinner_y_row.value = @y_row
		spinner_y_row.width_request = 40
		hbox_y_row = Gtk::HBox.new(false,0)
		vbox_y_row = Gtk::VBox.new(false,0)
		hbox1.pack_start(Gtk::Label.new(""),false,false,2.5) # 空白
		hbox1.pack_start(vbox_y_row,false,false,0)
		vbox_y_row.pack_start(Gtk::Label.new.set_markup("<small>Y</small>"),false,false,0)
		vbox_y_row.pack_start(hbox_y_row,false,false,0)
		hbox_y_row.pack_start(Gtk::Label.new("y="),false,false,0)
		hbox_y_row.pack_start(spinner_y_row,false,false,0)
		hbox_y_row.pack_start(Gtk::Label.new("列目"),false,false,3)
		## yデータ列変更時
		spinner_y_row.signal_connect("value_changed") do |w|
				@y_row = w.value_as_int
				#p @y_row = w.value_as_int
		end
		#}}}

		# Xプロット式 {{{
		hbox_x_expr = Gtk::HBox.new(false,0)
		vbox_x_expr = Gtk::VBox.new(false,0)
		#hbox_x_expr.border_width = 5
		hbox1.pack_start(hbox_x_expr,false,false,0)

		hbox_x_expr.pack_start(Gtk::Label.new(""),false,false,3) # 空白
		hbox_x_expr.pack_start(vbox_x_expr,false,false,0)
		vbox_x_expr.pack_start(Gtk::Label.new.set_markup("<small>Xプロット式</small>"),false,false,0)
		@entry_x_expr = Gtk::Entry.new
		### デフォルト値セット
		@entry_x_expr.text = @x_expr
		@entry_x_expr.width_request = 100
		vbox_x_expr.pack_start(@entry_x_expr,false,false,0)
		### 追加式変更時
		@entry_x_expr.signal_connect("changed") do |w|
			@x_expr = w.text
			#p @x_expr
		end
		#}}}

		# Yプロット式 {{{
		hbox_y_expr = Gtk::HBox.new(false,0)
		vbox_y_expr = Gtk::VBox.new(false,0)
		#hbox_y_expr.border_width = 5
		hbox1.pack_start(hbox_y_expr,false,false,0)

		hbox_y_expr.pack_start(Gtk::Label.new(""),false,false,3) # 空白
		hbox_y_expr.pack_start(vbox_y_expr,false,false,0)
		vbox_y_expr.pack_start(Gtk::Label.new.set_markup("<small>Yプロット式</small>"),false,false,0)
		@entry_y_expr = Gtk::Entry.new
		### デフォルト値セット
		@entry_y_expr.text = @y_expr
		@entry_y_expr.width_request = 100
		vbox_y_expr.pack_start(@entry_y_expr,false,false,0)
		### 追加式変更時
		@entry_y_expr.signal_connect("changed") do |w|
			@y_expr = w.text
			#p @y_expr
		end
		#}}}

		## 第2軸有効/無効チェックボックス {{{
		hbox_y2axis = Gtk::HBox.new(false,0)
		vbox_y2axis = Gtk::VBox.new(false,0)
		hbox1.pack_start(vbox_y2axis,false,false,0)
		vbox_y2axis.pack_start(Gtk::Label.new.set_markup("<small></small>"),false,false,0)
		vbox_y2axis.pack_start(hbox_y2axis,false,false,0)
		@check_y2axis = Gtk::CheckButton.new("第2Y軸")
		hbox_y2axis.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_y2axis.pack_start(@check_y2axis,false,false,0)
		@check_y2axis.active = @y2axis
		@check_y2axis.signal_connect("toggled") do |c|
			@y2axis = c.active?
			#p @y2axis
		end
		#}}}

		## 線色 {{{
		### メニューアイテム
		menu_items_linecolor = []

		@linecolor_menu_contents.each do |colorname,r,g,b|
			menuitem = get_item_linecolor(colorname,r,g,b)
			menu_items_linecolor << menuitem
		end
		menu_menu_linecolor = Gtk::Menu.new
		@opt_linecolor = Gtk::OptionMenu.new
		#@opt_linecolor.menu = item_factory.get_widget("<linecolor>")
		menu_items_linecolor.each do |item|
			menu_menu_linecolor.append(item)
		end
		@opt_linecolor.menu = menu_menu_linecolor
		hbox1.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_linecolor = Gtk::HBox.new(false,0)
		vbox_linecolor = Gtk::VBox.new(false,0)
		hbox1.pack_start(vbox_linecolor,false,false,0)
		vbox_linecolor.pack_end(hbox_linecolor,false,false,0)
		hbox_linecolor.pack_start(Gtk::Label.new("色 : "),false,false,0)
		hbox_linecolor.pack_start(@opt_linecolor,false,false,0)
		### デフォルト値セット
		update_linecolor()

		# gnuplot旧バージョンでは無効化
		@opt_linecolor.sensitive = !@option.flag_gp_old_ver

		#}}}

		## ポイントの種類 {{{
		# コールバック
		cb_pointtype = Proc.new do |*d|
			@pointtype = d[0]
			#p @pointtype
		end

		# xpm画像を定義 {{{
		xpm_pointtype = []

		# xpm pointtype 1
		xpm_pointtype[1] = [ #{{{
			'16 16 3 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #000000',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'++++++++++++++++',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......',
			'........+.......'
		] #}}}

		# xpm pointtype 2
		xpm_pointtype[2] = [ #{{{
			'16 16 12 1',
			' 	c None',
			'.	c #A8A8A8',
			'+	c #CACACA',
			'@	c #FFFFFF',
			'#	c #EDEDED',
			'$	c #656565',
			'%	c #0B0B0B',
			'&	c #979797',
			'*	c #555555',
			'=	c #070707',
			'-	c #090909',
			';	c #040404',
			'.+@@@@@@@@@@@@.#',
			'$%+@@@@@@@@@@&%+',
			'@*%+@@@@@@@@&%+@',
			'@@*%+@@@@@@&%+@@',
			'@@@*%+@@@@&%+@@@',
			'@@@@*%+@@&%+@@@@',
			'@@@@@*%+&%+@@@@@',
			'@@@@@@*=-+@@@@@@',
			'@@@@@@&;-+@@@@@@',
			'@@@@@&%+*%+@@@@@',
			'@@@@&%+@@*%+@@@@',
			'@@@&%+@@@@*%+@@@',
			'@@&%+@@@@@@*%+@@',
			'@&%+@@@@@@@@*%+@',
			'&%+@@@@@@@@@@*%+',
			'&+@@@@@@@@@@@@$+'
		] #}}}

		# xpm pointtype 3
		xpm_pointtype[3] = [ #{{{
			'16 16 10 1',
			' 	c None',
			'.	c #272727',
			'+	c #979797',
			'@	c #FFFFFF',
			'#	c #000000',
			'$	c #EDEDED',
			'%	c #363636',
			'&	c #DCDCDC',
			'*	c #555555',
			'=	c #CACACA',
			'.+@@@@@#@@@@@$%&',
			'+#+@@@@#@@@@$.*@',
			'@+#+@@@#@@@$.*@@',
			'@@+#+@@#@@$.*@@@',
			'@@@+#+@#@$.*@@@@',
			'@@@@+#+#$.*@@@@@',
			'@@@@@+##.*@@@@@@',
			'###############@',
			'@@@@@$.##+@@@@@@',
			'@@@@$.*#+#+@@@@@',
			'@@@$.*@#@+#+@@@@',
			'@@$.*@@#@@+#+@@@',
			'@$.*@@@#@@@+#+@@',
			'$.*@@@@#@@@@+#+@',
			'%*@@@@@#@@@@@+#=',
			'&@@@@@@@@@@@@@=@'
		] #}}}

		# xpm pointtype 4
		xpm_pointtype[4] = [ #{{{
			'15 16 3 1',
			' 	c None',
			'.	c #000000',
			'+	c #FFFFFF',
			'...............',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.++++++.++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'.+++++++++++++.',
			'...............'
		] #}}}

		# xpm pointtype 5
		xpm_pointtype[5] = [ #{{{
			'15 15 2 1',
			' 	c None',
			'.	c #000000',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............',
			'...............'
		] #}}}

		# xpm pointtype 6
		xpm_pointtype[6] = [ #{{{
			'17 16 18 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #979797',
			'@	c #454545',
			'#	c #363636',
			'$	c #000000',
			'%	c #555555',
			'&	c #B9B9B9',
			'*	c #CACACA',
			'=	c #191919',
			'-	c #868686',
			';	c #DCDCDC',
			'>	c #0B0B0B',
			',	c #EDEDED',
			'\'	c #757575',
			')	c #272727',
			'!	c #A8A8A8',
			'~	c #656565',
			'.....+@#$#%&.....',
			'...*==-&;&-=#;...',
			'..*>-......,%>*..',
			'.,>+.........\')..',
			'.%@...........)+.',
			'.>;...........!).',
			'&=.............$.',
			'&#......$......=*',
			'&#.............>;',
			';>............;$.',
			'.=!...........\'@.',
			'.+)..........,>&.',
			'..)%........,)%..',
			'..,)#;.....&)%...',
			'...,\'>)\'\'~)>-....',
			'.....,!\'\'\'!......'
		] #}}}

		# xpm pointtype 7
		xpm_pointtype[7] = [ #{{{
			'15 16 16 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #B9B9B9',
			'@	c #757575',
			'#	c #A8A8A8',
			'$	c #191919',
			'%	c #000000',
			'&	c #0B0B0B',
			'*	c #868686',
			'=	c #555555',
			'-	c #656565',
			';	c #EDEDED',
			'>	c #DCDCDC',
			',	c #363636',
			'\'	c #979797',
			')	c #CACACA',
			'.....+@@@#.....',
			'...#$%%%%%&*...',
			'..=%%%%%%%%%=..',
			'.*%%%%%%%%%%%-.',
			';&%%%%%%%%%%%%>',
			'*%%%%%%%%%%%%%-',
			',%%%%%%%%%%%%%,',
			',%%%%%%%%%%%%%&',
			',%%%%%%%%%%%%%$',
			'=%%%%%%%%%%%%%,',
			'\'%%%%%%%%%%%%%\'',
			'.$%%%%%%%%%%%&;',
			'.)&%%%%%%%%%%+.',
			'..)&%%%%%%%&#..',
			'...;@$%%%&=>...',
			'......;+;......'
		] #}}}

		# xpm pointtype 8
		xpm_pointtype[8] = [ #{{{
			'17 14 17 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #DCDCDC',
			'@	c #979797',
			'#	c #363636',
			'$	c #0B0B0B',
			'%	c #191919',
			'&	c #454545',
			'*	c #EDEDED',
			'=	c #A8A8A8',
			'-	c #B9B9B9',
			';	c #656565',
			'>	c #757575',
			',	c #272727',
			'\'	c #868686',
			')	c #CACACA',
			'!	c #000000',
			'.......+@........',
			'.......#$+.......',
			'......@%&&.......',
			'.....*$=*$-......',
			'.....;&..@%*.....',
			'....-$+...#>.....',
			'....,\'....)!+....',
			'...>,......>#....',
			'..+$-......*%@...',
			'..&;....!...=$*..',
			'.=$*.........&;..',
			'*%@..........+$-.',
			'>!############$,.',
			')---------------*'
		] #}}}

		# xpm pointtype 9
		xpm_pointtype[9] = [ #{{{
			'15 12 17 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #555555',
			'@	c #757575',
			'#	c #000000',
			'$	c #868686',
			'%	c #DCDCDC',
			'&	c #0B0B0B',
			'*	c #EDEDED',
			'=	c #363636',
			'-	c #454545',
			';	c #A8A8A8',
			'>	c #B9B9B9',
			',	c #191919',
			'\'	c #656565',
			')	c #272727',
			'!	c #979797',
			'.......+.......',
			'......@#$......',
			'.....%##&*.....',
			'.....=###-.....',
			'....;#####>....',
			'...*&#####,....',
			'...\'#######@...',
			'..>#########%..',
			'..)#########=..',
			'.$###########!.',
			'%&###########&*',
			'-#############\''
		] #}}}

		# xpm pointtype 10
		xpm_pointtype[10] = [ #{{{
			'17 14 18 1',
			' 	c None',
			'.	c #DCDCDC',
			'+	c #757575',
			'@	c #979797',
			'#	c #FFFFFF',
			'$	c #272727',
			'%	c #656565',
			'&	c #000000',
			'*	c #B9B9B9',
			'=	c #0B0B0B',
			'-	c #555555',
			';	c #454545',
			'>	c #EDEDED',
			',	c #A8A8A8',
			'\'	c #191919',
			')	c #868686',
			'!	c #363636',
			'~	c #CACACA',
			'.+++++++++++++++@',
			'#$$+++++++++++%&*',
			'#*=.##########-;#',
			'##%;#########*=>#',
			'##>=,###&####\')##',
			'###@\'>######+!###',
			'####!+#####.&~###',
			'####.&~####!%####',
			'#####+!###,\'>####',
			'#####>\'@#>=,#####',
			'######*=>%!######',
			'#######;!=.######',
			'#######.=+#######',
			'########,########'
		] #}}}

		# xpm pointtype 11
		xpm_pointtype[11] = [ #{{{
			'16 13 17 1',
			' 	c None',
			'.	c #B9B9B9',
			'+	c #363636',
			'@	c #EDEDED',
			'#	c #FFFFFF',
			'$	c #000000',
			'%	c #656565',
			'&	c #CACACA',
			'*	c #0B0B0B',
			'=	c #A8A8A8',
			'-	c #191919',
			';	c #DCDCDC',
			'>	c #454545',
			',	c #757575',
			'\'	c #272727',
			')	c #555555',
			'!	c #868686',
			'.++++++++++++++@',
			'#+$$$$$$$$$$$$%#',
			'#&$$$$$$$$$$$*@#',
			'##%$$$$$$$$$$=##',
			'##@-$$$$$$$$+###',
			'###=$$$$$$$$;###',
			'####>$$$$$$,####',
			'####;*$$$$-#####',
			'#####,$$$$.#####',
			'######\'$$>######',
			'######.$*@######',
			'#######)!#######',
			'#######@########'
		] #}}}

		# xpm pointtype 12
		xpm_pointtype[12] = [ #{{{
			'17 17 12 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #DCDCDC',
			'@	c #555555',
			'#	c #0B0B0B',
			'$	c #CACACA',
			'%	c #272727',
			'&	c #868686',
			'*	c #EDEDED',
			'=	c #979797',
			'-	c #000000',
			';	c #A8A8A8',
			'........+........',
			'.......@#$.......',
			'......@%&#$......',
			'.....@%*.=#$.....',
			'....@%*...=#$....',
			'...@%*.....=#$...',
			'..@%*.......=#$..',
			'.@%*.........=#$.',
			'&-+.....-.....@#*',
			'*%%*.........=-=.',
			'.*%%*.......=-=..',
			'..*%%*.....=-=...',
			'...*%%*...=-=....',
			'....*%%*.=-=.....',
			'.....*%%&-=......',
			'......*%-=.......',
			'.......*;........'
		] #}}}

		# xpm pointtype 13
		xpm_pointtype[13] = [ #{{{
			'15 15 11 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #CACACA',
			'@	c #656565',
			'#	c #0B0B0B',
			'$	c #000000',
			'%	c #555555',
			'&	c #868686',
			'*	c #979797',
			'=	c #272727',
			'-	c #EDEDED',
			'......+@.......',
			'.....+#$%......',
			'....+#$$$%.....',
			'...+#$$$$$%....',
			'..+#$$$$$$$%...',
			'.+#$$$$$$$$$%..',
			'+#$$$$$$$$$$$%.',
			'#$$$$$$$$$$$$$&',
			'*$$$$$$$$$$$$=-',
			'.*$$$$$$$$$$=-.',
			'..*$$$$$$$$=-..',
			'...*$$$$$$=-...',
			'....*$$$$=-....',
			'.....*$$=-.....',
			'......*=-......'
		] #}}}

		# xpm pointtype 14
		xpm_pointtype[14] = [ #{{{
			'15 15 18 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #868686',
			'@	c #EDEDED',
			'#	c #DCDCDC',
			'$	c #272727',
			'%	c #0B0B0B',
			'&	c #191919',
			'*	c #B9B9B9',
			'=	c #A8A8A8',
			'-	c #656565',
			';	c #757575',
			'>	c #555555',
			',	c #CACACA',
			'\'	c #363636',
			')	c #979797',
			'!	c #000000',
			'~	c #454545',
			'.......+@......',
			'.....#$%&*.....',
			'....=%-.+%;....',
			'..@>%=...,$\'#..',
			'.,$\'@.....@-%=.',
			')!+.........=%-',
			'~;...........=&',
			')$...........--',
			'@!#....!.....&,',
			'.~+.........,&.',
			'.)~.........->.',
			'.@!@........&=.',
			'..~).......,%..',
			'..)\'*******>>..',
			'..@\'\'\'\'\'\'\'\'\'*..'
		] #}}}

		# xpm pointtype 15
		xpm_pointtype[15] = [ #{{{
			'14 14 16 1',
			' 	c None',
			'.	c #FFFFFF',
			'+	c #656565',
			'@	c #454545',
			'#	c #EDEDED',
			'$	c #CACACA',
			'%	c #272727',
			'&	c #000000',
			'*	c #191919',
			'=	c #979797',
			'-	c #0B0B0B',
			';	c #757575',
			'>	c #363636',
			',	c #A8A8A8',
			'\'	c #555555',
			')	c #B9B9B9',
			'......+@#.....',
			'....$%&&*$....',
			'...=-&&&&&;...',
			'.#@&&&&&&&&>#.',
			'$*&&&&&&&&&&-,',
			'*&&&&&&&&&&&&&',
			'+&&&&&&&&&&&&@',
			'$&&&&&&&&&&&&=',
			'.*&&&&&&&&&&&#',
			'.+&&&&&&&&&&@.',
			'.,&&&&&&&&&&=.',
			'..-&&&&&&&&&#.',
			'..\'&&&&&&&&@..',
			'..$;;;;;;;;)..'
		] #}}}

		# xpm画像を定義 ここまで }}}

		### メニューアイテム
		get_item_pointtype = Proc.new do |item,i|
			pixbuf = Gdk::Pixbuf.new(xpm_pointtype[i]).add_alpha(true,255,255,255)
			image = Gtk::Image.new(pixbuf)
			event_box = Gtk::EventBox.new.add(image)
			#box.width_request = 17
			#box.height_request = 17
			item.add(event_box)
		end

		menu_items_pointtype = []

		pointtype_order = [ 12, 6, 4, 8, 10, 13, 7, 5, 9, 11, 1,]
		pointtype_order.each do |i|
			menuitem = Gtk::MenuItem.new
			get_item_pointtype.call(menuitem,i)
			menuitem.signal_connect("activate"){cb_pointtype.call(i)}
			menu_items_pointtype << menuitem
		end
		menu_menu_pointtype = Gtk::Menu.new
		@opt_pointtype = Gtk::OptionMenu.new
		#@opt_pointtype.menu = item_factory.get_widget("<pointtype>")
		menu_items_pointtype.each do |item|
			menu_menu_pointtype.append(item)
		end
		@opt_pointtype.menu = menu_menu_pointtype
		hbox1.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_pointtype = Gtk::HBox.new(false,0)
		vbox_pointtype = Gtk::VBox.new(false,0)
		hbox1.pack_start(vbox_pointtype,false,false,0)
		vbox_pointtype.pack_end(hbox_pointtype,false,false,0)
		hbox_pointtype.pack_start(Gtk::Label.new("ポイント : "),false,false,0)
		hbox_pointtype.pack_start(@opt_pointtype,false,false,0)
		### デフォルト値セット
		update_pointtype()

		#}}}


		# 2列目
		hbox2 = Gtk::HBox.new(false,0)
		vbox_info.pack_start(hbox2,false,false,0)

		## タイトル {{{
		hbox_title = Gtk::HBox.new(false,0)
		#hbox_title.border_width = 0
		hbox2.pack_start(hbox_title,false,false,0)

		hbox_title.pack_start(Gtk::Label.new("タイトル : "),false,false,0)
		@entry_title = Gtk::Entry.new
		@entry_title.width_request = 200
		### デフォルト値セット
		@entry_title.text = @title
		hbox_title.pack_start(@entry_title,true,true,0)
		### タイトル変更時
		@entry_title.signal_connect("changed") do |w|
			@title = w.text
			#p @title
		end
		#}}}

		## プロットスタイル {{{
		# コールバック
		cb_style = Proc.new do |*d|
			@linestyle = d[0]
			#p @linestyle
		end
		### メニューアイテム
		menu_items_style = [
			["/線のみ",Gtk::ItemFactory::ITEM,nil,nil,cb_style,"lines"],
			["/線とポイント",Gtk::ItemFactory::ITEM,nil,nil,cb_style,"linespoints"],
			["/ポイントのみ",Gtk::ItemFactory::ITEM,nil,nil,cb_style,"points"],
		]
		item_factory = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_MENU, "<style>", nil)
		item_factory.create_items(menu_items_style)
		@opt_style = Gtk::OptionMenu.new
		@opt_style.menu = item_factory.get_widget("<style>")
		hbox2.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox2.pack_start(Gtk::Label.new("スタイル : "),false,false,0)
		hbox2.pack_start(@opt_style,false,false,0)
		### デフォルト値セット
		case @linestyle
		when "lines"
			@opt_style.history = 0
		when "linespoints"
			@opt_style.history = 1
		when "points"
			@opt_style.history = 2
		end
		#}}}

		# 線幅 {{{
		@adj_linewidth = Gtk::Adjustment.new(2, 1, 20, 1, 1, 0)
		spinner_linewidth = Gtk::SpinButton.new(@adj_linewidth, 0.0, 0)
		spinner_linewidth.wrap = false
		## デフォルト値セット
		spinner_linewidth.value = @linewidth
		spinner_linewidth.width_request = 40
		hbox2.pack_start(Gtk::Label.new(""),false,false,2.5) # 空白
		hbox2.pack_start(Gtk::Label.new("線幅 : "),false,false,0)
		hbox2.pack_start(spinner_linewidth,false,false,0)
		## 線幅変更時
		spinner_linewidth.signal_connect("value_changed") do |w|
				@linewidth = w.value_as_int
				#p @linewidth = w.value_as_int
		end
		#}}}

		## 線種 {{{
		cb_type = Proc.new do |*d|
			@linetype = d[0]
			#p @linetype
		end
		### 線描画コールバック
		### offset:dashesの何番目から描画スタートするか
		### dashes:線、空白、線、空白...の長さ
		get_item_linetype = Proc.new do |item,type,offset,dashes|
			vbox_area = Gtk::VBox.new(false,0)
			vbox_area.height_request = 15
			area = Gtk::DrawingArea.new
			vbox_area.pack_start(area,true,false,0)
			area.width_request = 60
			lw = 2
			area.height_request = lw
			area.signal_connect("expose_event") do
				alloc = area.allocation
				aw = alloc.width
				ah = alloc.height
				#gc = area.style.fg_gc(area.state)
				gc = area.style.fg_gc(Gtk::STATE_NORMAL)
				#gc_clr = area.style.bg_gc(area.state)
				#area.window.draw_rectangle(gc_clr,true,0,0,aw,ah)
				lw_def = gc.line_attributes[0]
				if type == 1 then
					gc.set_line_attributes(lw,Gdk::GC::LINE_SOLID,
										   Gdk::GC::CAP_BUTT,Gdk::GC::JOIN_MITER)
				else
					gc.set_line_attributes(lw,Gdk::GC::LINE_ON_OFF_DASH,
										   Gdk::GC::CAP_BUTT,Gdk::GC::JOIN_MITER)
					gc.set_dashes(offset,dashes)
				end
				area.window.draw_line(gc,0,ah/2,aw,ah/2)
				#area.window.draw_rectangle(gc,true,5,(ah-lw)/2,aw-10,lw)
				gc.set_line_attributes(lw_def,Gdk::GC::LINE_ON_OFF_DASH,
									   Gdk::GC::CAP_BUTT,Gdk::GC::JOIN_MITER)
				#p area.drawable?
			end
			item.add(vbox_area)

			## 線幅変更時にも線種の描画を更新
			#spinner_linewidth.signal_connect("value_changed") do |w|
			#	area.signal_emit("expose_event",nil)
			#end

		end

		menu_items_linetype = []

		[
			[1,0,],
			[2,0,5,2,],
			[3,0,3,3,],
			[4,0,2,2,],
			[5,0,9,2,2,2,],
			[6,0,5,4,2,4,],
			[7,0,3,2,3,6,],
			[8,0,9,2,2,2,2,2,],
			[9,0,2,2,2,2,2,2,2,5,],
		].each do |type,offset,*dashes|
			menuitem = Gtk::MenuItem.new
			get_item_linetype.call(menuitem,type,offset,dashes)
			menuitem.signal_connect("activate"){cb_type.call(type)}
			menu_items_linetype << menuitem
		end
		menu_menu_linetype = Gtk::Menu.new
		@opt_linetype = Gtk::OptionMenu.new
		menu_items_linetype.each do |item|
			menu_menu_linetype.append(item)
		end
		@opt_linetype.menu = menu_menu_linetype
		hbox2.pack_start(Gtk::Label.new(""),false,false,2.5) # 空白
		hbox2.pack_start(Gtk::Label.new("線種 : "),false,false,0)
		hbox2.pack_start(@opt_linetype,false,false,0)

		#}}}

		## セパレータ
		hbox_contents.pack_start(Gtk::VSeparator.new,true,false,0)

		## 系列削除ボタン {{{
		vbox_del_button = Gtk::VBox.new(false,0)
		delete_button = Gtk::Button.new("削除")
		vbox_del_button.pack_start(delete_button,true,false,0)
		hbox_contents.pack_end(vbox_del_button,false,false,0)
		delete_button.signal_connect("clicked") do
			parent.remove(self)
			parent.each do |c|
				c.update_updown
			end
		end
		#delete_button.sensitive = false if sw
		#}}}

		## 上へ・下へボタン {{{
		vbox_up_down_button = Gtk::VBox.new(false,0)
		hbox_contents.pack_end(vbox_up_down_button,false,false,0)
		### 上へ
		@go_up_button = Gtk::Button.new
		@go_up_button.add(Gtk::Image.new(Gtk::Stock::GO_UP,Gtk::IconSize::BUTTON))
		vbox_up_down_button.pack_start(@go_up_button,true,false,0)
		@go_up_button.signal_connect("clicked") do
			#p "up"
			tmp_i = 0
			parent.each do |c|
				tmp_i += 1
				break if c == self
			end
			#p tmp_i
			parent.reorder_child(self,tmp_i-2)
			parent.each do |c|
				c.update_updown
			end
		end
		### 下へ
		@go_down_button = Gtk::Button.new
		@go_down_button.add(Gtk::Image.new(Gtk::Stock::GO_DOWN,Gtk::IconSize::BUTTON))
		vbox_up_down_button.pack_start(@go_down_button,true,false,0)
		@go_down_button.signal_connect("clicked") do
			#p "down"
			tmp_i = 0
			parent.each do |c|
				tmp_i += 1
				break if c == self
			end
			#p tmp_i
			parent.reorder_child(self,tmp_i)
			parent.each do |c|
				c.update_updown
			end
		end
		#}}}

		## セパレータ
		vbox_contents.pack_start(Gtk::HSeparator.new,false,false,0)
	end #}}}
end
#}}}

# オプション設定クラス
# ダイアログのサブクラス
class OptionDialog #{{{
	def get_contents #{{{
		vbox_contents = Gtk::VBox.new(false,0)
		#label = Gtk::Label.new("制作中")
		#vbox_contents.pack_start(label,true,true,20)
		# コマンド設定部 #{{{
		frame_cmd = Gtk::Frame.new("コマンド")
		vbox_contents.pack_start(frame_cmd,false,false,0)
		vbox_cmd = Gtk::VBox.new(false,0)
		frame_cmd.add(vbox_cmd)

		## gnuplotパス
		hbox_cmd_gnuplot = Gtk::HBox.new(false,0)
		hbox_cmd_gnuplot.border_width = 5
		vbox_cmd.pack_start(hbox_cmd_gnuplot,false,false,0)

		hbox_cmd_gnuplot.pack_start(Gtk::Label.new("gnuplot : "),false,false,0)
		entry_cmd_gnuplot = Gtk::Entry.new
		## デフォルト値セット
		entry_cmd_gnuplot.text = @cmd_gnuplot
		hbox_cmd_gnuplot.pack_start(entry_cmd_gnuplot,true,true,0)
		## コマンドパス変更時
		entry_cmd_gnuplot.signal_connect("changed") do |w|
			@tmp_cmd_gnuplot = w.text
			#p @tmp_cmd_gnuplot
		end

		## eps閲覧コマンドパス
		hbox_cmd_epsview = Gtk::HBox.new(false,0)
		hbox_cmd_epsview.border_width = 5
		vbox_cmd.pack_start(hbox_cmd_epsview,false,false,0)

		hbox_cmd_epsview.pack_start(Gtk::Label.new("epsビューア : "),false,false,0)
		entry_cmd_epsview = Gtk::Entry.new
		## デフォルト値セット
		entry_cmd_epsview.text = @cmd_epsview
		hbox_cmd_epsview.pack_start(entry_cmd_epsview,true,true,0)
		## コマンドパス変更時
		entry_cmd_epsview.signal_connect("changed") do |w|
			@tmp_cmd_epsview = w.text
			#p @tmp_cmd_epsview
		end

		## eps->png変換コマンドパス
		hbox_cmd_pngconv = Gtk::HBox.new(false,0)
		hbox_cmd_pngconv.border_width = 5
		vbox_cmd.pack_start(hbox_cmd_pngconv,false,false,0)

		hbox_cmd_pngconv.pack_start(Gtk::Label.new("eps->png変換 : "),false,false,0)
		entry_cmd_pngconv = Gtk::Entry.new
		entry_cmd_pngconv.width_request = 270
		vbox_cmd.pack_start(Gtk::Label.new("(%e:epsファイルパス, %p:pngファイルパス)"),false,false,0)
		## デフォルト値セット
		entry_cmd_pngconv.text = @cmd_pngconv
		hbox_cmd_pngconv.pack_start(entry_cmd_pngconv,true,true,0)
		## コマンドパス変更時
		entry_cmd_pngconv.signal_connect("changed") do |w|
			@tmp_cmd_pngconv = w.text
			#p @tmp_cmd_pngconv
		end

		## png閲覧コマンドパス
		hbox_cmd_pngview = Gtk::HBox.new(false,0)
		hbox_cmd_pngview.border_width = 5
		vbox_cmd.pack_start(hbox_cmd_pngview,false,false,0)

		hbox_cmd_pngview.pack_start(Gtk::Label.new("pngビューア : "),false,false,0)
		entry_cmd_pngview = Gtk::Entry.new
		## デフォルト値セット
		entry_cmd_pngview.text = @cmd_pngview
		hbox_cmd_pngview.pack_start(entry_cmd_pngview,true,true,0)
		## コマンドパス変更時
		entry_cmd_pngview.signal_connect("changed") do |w|
			@tmp_cmd_pngview = w.text
			#p @tmp_cmd_pngview
		end

		## データファイル閲覧コマンドパス
		hbox_cmd_datafileview = Gtk::HBox.new(false,0)
		hbox_cmd_datafileview.border_width = 5
		vbox_cmd.pack_start(hbox_cmd_datafileview,false,false,0)

		hbox_cmd_datafileview.pack_start(Gtk::Label.new("データファイルビューア : "),false,false,0)
		entry_cmd_datafileview = Gtk::Entry.new
		## デフォルト値セット
		entry_cmd_datafileview.text = @cmd_datafileview
		hbox_cmd_datafileview.pack_start(entry_cmd_datafileview,true,true,0)
		## コマンドパス変更時
		entry_cmd_datafileview.signal_connect("changed") do |w|
			@tmp_cmd_datafileview = w.text
			#p @tmp_cmd_datafileview
		end

		#}}}

		# プロット設定部 {{{
		frame_plot = Gtk::Frame.new("プロット")
		vbox_contents.pack_start(frame_plot,false,false,0)
		vbox_plot = Gtk::VBox.new(false,0)
		frame_plot.add(vbox_plot)

		## データファイル検索パターン
		hbox_plot_datapattern = Gtk::HBox.new(false,0)
		hbox_plot_datapattern.border_width = 5
		vbox_plot.pack_start(hbox_plot_datapattern,false,false,0)

		hbox_plot_datapattern.pack_start(Gtk::Label.new("データファイルパターン : "),false,false,0)
		entry_plot_datapattern = Gtk::Entry.new
		## デフォルト値セット
		entry_plot_datapattern.text = @plot_datapattern
		hbox_plot_datapattern.pack_start(entry_plot_datapattern,true,true,0)
		## データファイル検索パターン変更時
		entry_plot_datapattern.signal_connect("changed") do |w|
			@tmp_plot_datapattern = w.text
			#p @tmp_plot_datapattern
		end

		## データファイル選択時にプロット対象列をリセット
		hbox_plot_resetrow = Gtk::HBox.new(false,0)
		hbox_plot_resetrow.border_width = 5
		vbox_plot.pack_start(hbox_plot_resetrow,false,false,0)

		check_plot_resetrow = Gtk::CheckButton.new("データファイル選択時にプロット対象列をリセットする")
		## デフォルト値セット
		check_plot_resetrow.active = @plot_resetrow
		hbox_plot_resetrow.pack_start(check_plot_resetrow,true,true,0)
		## データファイル検索パターン変更時
		check_plot_resetrow.signal_connect("toggled") do |w|
			@tmp_plot_resetrow = w.active?
		end

		#}}}

		# フォント設定部 #{{{
		frame_font = Gtk::Frame.new("フォント")
		vbox_contents.pack_start(frame_font,false,false,0)
		vbox_font = Gtk::VBox.new(false,0)
		frame_font.add(vbox_font)

		## X11ターミナルフォント
		hbox_x11_fontsize = Gtk::HBox.new(false,0)
		hbox_x11_fontsize.border_width = 5
		# 現在無効(非表示)
		#vbox_font.pack_start(hbox_x11_fontsize,false,false,0)

		hbox_x11_fontsize.pack_start(Gtk::Label.new("プレビューフォントサイズ : "),false,false,0)
		entry_x11_fontsize = Gtk::Entry.new
		entry_x11_fontsize.width_request = 30
		## デフォルト値セット
		entry_x11_fontsize.text = @x11_fontsize
		hbox_x11_fontsize.pack_start(entry_x11_fontsize,false,false,0)
		## フォントサイズ変更時
		entry_x11_fontsize.signal_connect("changed") do |w|
			@tmp_x11_fontsize = w.text
			#p @tmp_x11_fontsize
		end

		## 出力に使用するフォント名
		hbox_fontname = Gtk::HBox.new(false,0)
		hbox_fontname.border_width = 5
		vbox_font.pack_start(hbox_fontname,false,false,0)

		hbox_fontname.pack_start(Gtk::Label.new("出力に使うフォント名 : "),false,false,0)
		entry_fontname = Gtk::Entry.new
		#entry_fontname.width_request = 30
		## デフォルト値セット
		entry_fontname.text = @fontname
		hbox_fontname.pack_start(entry_fontname,false,false,0)
		## フォントサイズ変更時
		entry_fontname.signal_connect("changed") do |w|
			@tmp_fontname = w.text
			#p @tmp_fontname
		end

		#}}}

		# デフォルトに戻すボタン
		button_reset = Gtk::Button.new("デフォルトに戻す")
		hbox_reset = Gtk::HBox.new(false,0)
		vbox_contents.pack_start(hbox_reset,false,false,5)
		hbox_reset.pack_end(button_reset,false,false,0)
		button_reset.signal_connect("clicked") do
			entry_cmd_gnuplot.text      = @default_values['cmd_gnuplot']
			entry_cmd_epsview.text      = @default_values['cmd_epsview']
			entry_cmd_pngconv.text      = @default_values['cmd_pngconv']
			entry_cmd_pngview.text      = @default_values['cmd_pngview']
			entry_cmd_datafileview.text = @default_values['cmd_datafileview']
			entry_plot_datapattern.text = @default_values['plot_datapattern']
			check_plot_resetrow.active  = @default_values['plot_resetrow']
			entry_x11_fontsize.text     = @default_values['x11_fontsize']
			entry_fontname.text         = @default_values['fontname']
		end

		return vbox_contents
	end #}}}

	def apply(window) #{{{
		# コマンドが実在するかチェック
		not_found_cmds = []
		[
			@tmp_cmd_gnuplot     ,
			@tmp_cmd_epsview     ,
			@tmp_cmd_pngconv     ,
			@tmp_cmd_pngview     ,
			@tmp_cmd_datafileview,
		].each do |cmd|
			cmd0 = cmd.split(/\s+/)[0]
			`which #{cmd0} >& /dev/null` # (systemよりも``のほうが高速)
			not_found_cmds << cmd0 unless $?.exitstatus == 0
		end

		# 適用するときの動作
		proc_ok = Proc.new do
			# 値を適用する
			@cmd_gnuplot      = @tmp_cmd_gnuplot
			@cmd_epsview      = @tmp_cmd_epsview
			@cmd_pngconv      = @tmp_cmd_pngconv
			@cmd_pngview      = @tmp_cmd_pngview
			@cmd_datafileview = @tmp_cmd_datafileview
			@plot_datapattern = @tmp_plot_datapattern
			@plot_resetrow    = @tmp_plot_resetrow
			@x11_fontsize     = @tmp_x11_fontsize
			@fontname         = @tmp_fontname

			# gnuplotのバージョン判定
			gp_old_ver_check()

			write()
			window.destroy
		end

		# コマンドが見つからず、キャンセル時の動作
		proc_cancel = Proc.new do  end

		if not_found_cmds.length > 0 then
			errstr = "コマンドが見つかりません:\n\n"
			not_found_cmds.each do |cmd|
				errstr += cmd
				errstr += "\n"
			end
			errstr += "\n無視して続行しますか?\n"
			#@msgdialog.error_dialog(errstr)
			#return nil
			flag_continue = false
			@msgdialog.confirm_dialog(errstr,proc_ok,proc_cancel)
			return false
		end

		proc_ok.call
		return true
	end #}}}

	def write #{{{
		f = open(@savefile,"w")
		s = <<-EOS
		# This file is made by gpgui.
		@option.cmd_gnuplot="#{@cmd_gnuplot}"
		@option.cmd_epsview="#{@cmd_epsview}"
		@option.cmd_pngconv="#{@cmd_pngconv}"
		@option.cmd_pngview="#{@cmd_pngview}"
		@option.cmd_datafileview="#{@cmd_datafileview}"
		@option.plot_datapattern="#{@plot_datapattern}"
		@option.plot_resetrow="#{@plot_resetrow}"
		@option.fontname="#{@fontname}"
		EOS
		# 現在無効
		#s += "@option.x11_fontsize=\"#{@x11_fontsize}\"\n"
		s.each do |l|
			f.puts l.strip
		end
		f.close
	end #}}}

	def show #{{{
		tmpset()
		d = Gtk::Dialog.new("設定",nil,Gtk::Dialog::NO_SEPARATOR)
		d.vbox.pack_start(get_contents(),true,true,20)
		d.add_button(Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK)
		d.add_button(Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL)
		d.default_response = Gtk::Dialog::RESPONSE_CANCEL
		d.signal_connect("response") do |widget,response|
			case response
			when Gtk::Dialog::RESPONSE_OK
				apply(d)
			when Gtk::Dialog::RESPONSE_CANCEL
				d.destroy
			end
		end
		d.show_all
	end #}}}

	def tmpset #{{{
		@tmp_cmd_gnuplot      = @cmd_gnuplot
		@tmp_cmd_epsview      = @cmd_epsview
		@tmp_cmd_pngconv      = @cmd_pngconv
		@tmp_cmd_pngview      = @cmd_pngview
		@tmp_cmd_datafileview = @cmd_datafileview
		@tmp_plot_datapattern = @plot_datapattern
		@tmp_plot_resetrow    = @plot_resetrow
		@tmp_x11_fontsize     = @x11_fontsize
		@tmp_fontname         = @fontname
	end #}}}

	# gnuplotのバージョン判定
	def gp_old_ver_check #{{{
		@flag_gp_old_ver = false
		`which #{@cmd_gnuplot} >& /dev/null` # (systemよりも``のほうが高速)
		unless $?.exitstatus == 0
			#p "gnuplot not found"
			@msgdialog.error_dialog("gnuplotコマンド\n#{@cmd_gnuplot}\nが見つかりません。")
			return false 
		end
		`#{@cmd_gnuplot} --version` =~ /gnuplot\s+(\d+)\.(\d+)\s+patchlevel\s+(\d+)/
		@flag_gp_old_ver = true if $1.to_i < 4
		@flag_gp_old_ver = true if $1.to_i == 4 && $2.to_i < 2
		#p @flag_gp_old_ver
		return @flag_gp_old_ver
	end #}}}

	def set_defaults #{{{
		@cmd_gnuplot      = @default_values['cmd_gnuplot']
		@cmd_epsview      = @default_values['cmd_epsview']
		@cmd_pngconv      = @default_values['cmd_pngconv']
		@cmd_pngview      = @default_values['cmd_pngview']
		@cmd_datafileview = @default_values['cmd_datafileview']
		@plot_datapattern = @default_values['plot_datapattern']
		@plot_resetrow    = @default_values['plot_resetrow']
		@x11_fontsize     = @default_values['x11_fontsize']
		@fontname         = @default_values['fontname']
		@savefile         = @default_values['savefile']
	end #}}}

	def initialize #{{{
		@msgdialog            = MessageDialog.new
		@ins_general      = nil # ページ設定のインスタンス格納変数
		@default_values = {
			'cmd_gnuplot'      => "gnuplot",
			'cmd_epsview'      => "gv",
			'cmd_pngconv'      => "epstoimg -q -w 1000 -o %p %e",
			'cmd_pngview'      => "eog",
			'cmd_datafileview' => "gedit",
			'plot_datapattern' => "*.dat;*.csv;*.vcsv;*.tsv",
			'plot_resetrow'    => false,
			'x11_fontsize'     => "20",
			'fontname'         => "Arial",
			'savefile'         => File.join(ENV['HOME'],".gpgui"),
		}
		set_defaults()
		tmpset()
		gp_old_ver_check()
	end #}}}
	attr_accessor :cmd_gnuplot, :cmd_epsview, :cmd_pngconv, :cmd_pngview, :cmd_datafileview,
		:plot_datapattern, :plot_resetrow,
		:x11_fontsize, :fontname,
		:savefile, :flag_gp_old_ver, :ins_general

	def cmd_gpfileview #{{{
		@cmd_datafileview
	end
	#}}}

end
#}}}

# データファイルクラス
# VBoxのサブクラス
class Datafiles < Gtk::VBox #{{{
end
#}}}

# 全般設定ページクラス
# VBoxのサブクラス
class PageGeneral < Gtk::VBox #{{{
	def get_page_general #{{{
		# 全体の格納ボックス
		vbox_contents = Gtk::VBox.new(false,5)
		vbox_contents.border_width = 10

		# データファイル設定部 {{{
		frame_datafile = Gtk::Frame.new("デフォルトデータファイル")
		vbox_contents.pack_start(frame_datafile,false,false,0)

		hbox_datafile = Gtk::HBox.new(false,0)
		hbox_datafile.border_width = 5
		frame_datafile.add(hbox_datafile)

		hbox_datafile.pack_start(Gtk::Label.new("ファイルパス : "),false,false,0)
		@entry_datafile = Gtk::Entry.new
		@entry_datafile.text = @datafile
		hbox_datafile.pack_start(@entry_datafile,true,true,0)

		## データファイル参照ボタン
		button_datafile = FileChooserButton2.new()
		hbox_datafile.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_datafile.pack_end(button_datafile,false,false,0)

		filter_all = Gtk::FileFilter.new.add_pattern("*")
		filter_all.name = ("All Files (*)")
		button_datafile.dialog.add_filter(filter_all)
		filter_datas = Gtk::FileFilter.new
		filter_datas.add_pattern("*.dat")
		filter_datas.add_pattern("*.csv")
		filter_datas.add_pattern("*.vcsv")
		filter_datas.add_pattern("*.tsv")
		filter_datas.name = ("DataFiles (*.dat *.csv *.vcsv *tsv)")
		button_datafile.dialog.add_filter(filter_datas)
		filter_dat = Gtk::FileFilter.new.add_pattern("*.dat")
		filter_dat.name = ("*.dat")
		button_datafile.dialog.add_filter(filter_dat)
		filter_csv = Gtk::FileFilter.new.add_pattern("*.csv")
		filter_csv.name = ("*.csv")
		button_datafile.dialog.add_filter(filter_csv)
		filter_vcsv = Gtk::FileFilter.new.add_pattern("*.vcsv")
		filter_vcsv.name = ("*.vcsv")
		button_datafile.dialog.add_filter(filter_vcsv)
		filter_tsv = Gtk::FileFilter.new.add_pattern("*.tsv")
		filter_tsv.name = ("*.tsv")
		button_datafile.dialog.add_filter(filter_tsv)
		button_datafile.dialog.filter = filter_datas

		## データファイルパス変更時
		@entry_datafile.signal_connect("changed") do |w|
			@datafile = w.text
			#p @datafile
			if File.directory?(@datafile) then
				button_datafile.current_folder = @datafile
			elsif File.directory?(File.dirname(@datafile)) then
				button_datafile.current_folder = File.dirname(@datafile)
			end
		end

		## データファイル参照ボタンが押された時のコールバック
		## 後で定義

		## データファイル閲覧ボタン
		button_datafile_view = Gtk::Button.new("閲覧...")
		hbox_datafile.pack_end(button_datafile_view,false,false,0)
		#hbox_datafile.pack_end(Gtk::Label.new(""),false,false,5) # 空白
		button_datafile_view.signal_connect("clicked") do
			#p @datafile
			#p @option.cmd_datafileview
			if File.exist?(@datafile) then
				pid = fork{
					exec(@option.cmd_datafileview+' "'+@datafile+'"')
				}
				Process.detach(pid)
				#$child_pids << pid
			else
				@msgdialog.error_dialog("存在しないデフォルトデータファイルパスです。:\n\"#{@datafile}\"")
			end
		end
		#}}}

		# 区切り文字(スペース、コンマ、タブ) {{{
		frame_separator = Gtk::Frame.new("区切り文字")
		vbox_contents.pack_start(frame_separator,false,false,0)

		hbox_separator = Gtk::HBox.new(false,0)
		hbox_separator.border_width = 5
		frame_separator.add(hbox_separator)

		radio_separator_ws = Gtk::RadioButton.new("スペース")
		radio_separator_com = Gtk::RadioButton.new(radio_separator_ws,"コンマ")
		radio_separator_tab = Gtk::RadioButton.new(radio_separator_ws,"タブ")
		hbox_separator.pack_start(radio_separator_ws,false,false,10)
		hbox_separator.pack_start(radio_separator_com,false,false,10)
		hbox_separator.pack_start(radio_separator_tab,false,false,10)

		### ボタンと値の対応
		@hash_separator_value = {
			radio_separator_ws => "whitespace",
			radio_separator_com => ",",
			radio_separator_tab => "\\t",
		}

		### デフォルト値セット
		@radio_separator_group = radio_separator_ws.group
		@radio_separator_group.each do |r|
			r.active = true if @hash_separator_value[r] == @separator
		end

		### 区切り文字変更時
		@radio_separator_group.each do |r|
			r.signal_connect("toggled") do
				@separator = @hash_separator_value[r]
				#p @separator
			end
		end
		#}}}

		# コメント開始文字設定部 {{{
		frame_commentschars = Gtk::Frame.new("コメント開始文字")
		vbox_contents.pack_start(frame_commentschars,false,false,0)

		hbox_commentschars = Gtk::HBox.new(false,0)
		hbox_commentschars.border_width = 5
		frame_commentschars.add(hbox_commentschars)

		hbox_commentschars.pack_start(Gtk::Label.new("文字を続けて列挙 : "),false,false,0)
		@entry_commentschars = Gtk::Entry.new
		@entry_commentschars.text = @commentschars
		hbox_commentschars.pack_start(@entry_commentschars,true,true,0)
		## コメント文字変更時
		@entry_commentschars.signal_connect("changed") do |w|
			@commentschars = w.text
			#p @commentschars
		end
		#}}}

		# スクリプト出力設定部 {{{
		frame_gpfile = Gtk::Frame.new("スクリプト出力")
		vbox_contents.pack_start(frame_gpfile,false,false,0)

		hbox_gpfile = Gtk::HBox.new(false,0)
		hbox_gpfile.border_width = 5
		frame_gpfile.add(hbox_gpfile)

		hbox_gpfile.pack_start(Gtk::Label.new("ファイルパス : "),false,false,0)
		@entry_gpfile = Gtk::Entry.new
		@entry_gpfile.text = @gpfile
		hbox_gpfile.pack_start(@entry_gpfile,true,true,0)
		## gpファイル参照ボタン
		button_gpfile = FileChooserButton2.new("SAVE",nil,"スクリプト出力")
		hbox_gpfile.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_gpfile.pack_end(button_gpfile,false,false,0)

		filter_all = Gtk::FileFilter.new.add_pattern("*")
		filter_all.name = ("All Files (*)")
		button_gpfile.dialog.add_filter(filter_all)
		filter_gp = Gtk::FileFilter.new.add_pattern("*.gp")
		filter_gp.name = ("*.gp")
		button_gpfile.dialog.add_filter(filter_gp)
		button_gpfile.dialog.filter = filter_gp

		## gpファイルパス変更時
		@entry_gpfile.signal_connect("changed") do |w|
			@gpfile = w.text
			#p @gpfile
			if File.directory?(@gpfile) then
				button_gpfile.current_folder = @gpfile
			elsif File.directory?(File.dirname(@gpfile)) then
				button_gpfile.current_folder = File.dirname(@gpfile)
			end
		end
		## gpファイル閲覧ボタン
		button_gpfile_view = Gtk::Button.new("閲覧...")
		hbox_gpfile.pack_end(button_gpfile_view,false,false,0)
		#hbox_gpfile.pack_end(Gtk::Label.new(""),false,false,5) # 空白
		button_gpfile_view.signal_connect("clicked") do
			#p @gpfile
			#p @option.cmd_gpfileview
			if File.exist?(@gpfile) then
				pid = fork{
					exec(@option.cmd_gpfileview+' "'+@gpfile+'"')
				}
				Process.detach(pid)
				#$child_pids << pid
			else
				@msgdialog.error_dialog("スクリプトが存在しません:\n\"#{@gpfile}\"")
			end
		end
		#}}}

		# eps出力設定部 {{{
		frame_epsfile = Gtk::Frame.new("eps出力")
		vbox_contents.pack_start(frame_epsfile,false,false,0)

		hbox_epsfile = Gtk::HBox.new(false,0)
		hbox_epsfile.border_width = 5
		frame_epsfile.add(hbox_epsfile)

		hbox_epsfile.pack_start(Gtk::Label.new("ファイルパス : "),false,false,0)
		@entry_epsfile = Gtk::Entry.new
		@entry_epsfile.text = @epsfile
		hbox_epsfile.pack_start(@entry_epsfile,true,true,0)
		## epsファイル参照ボタン
		button_epsfile = FileChooserButton2.new("SAVE",nil,"eps出力")
		hbox_epsfile.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_epsfile.pack_end(button_epsfile,false,false,0)

		filter_all = Gtk::FileFilter.new.add_pattern("*")
		filter_all.name = ("All Files (*)")
		button_epsfile.dialog.add_filter(filter_all)
		filter_eps = Gtk::FileFilter.new.add_pattern("*.eps")
		filter_eps.name = ("*.eps")
		button_epsfile.dialog.add_filter(filter_eps)
		button_epsfile.dialog.filter = filter_eps

		## epsファイルパス変更時
		@entry_epsfile.signal_connect("changed") do |w|
			@epsfile = w.text
			#p @epsfile
			if File.directory?(@epsfile) then
				button_epsfile.current_folder = @epsfile
			elsif File.directory?(File.dirname(@epsfile)) then
				button_epsfile.current_folder = File.dirname(@epsfile)
			end
		end
		## epsファイル閲覧ボタン
		button_epsfile_view = Gtk::Button.new("閲覧...")
		hbox_epsfile.pack_end(button_epsfile_view,false,false,0)
		#hbox_epsfile.pack_end(Gtk::Label.new(""),false,false,5) # 空白
		button_epsfile_view.signal_connect("clicked") do
			#p @epsfile
			#p @option.cmd_epsview
			if File.exist?(@epsfile) then
				pid = fork{
					exec(@option.cmd_epsview+' "'+@epsfile+'"')
				}
				Process.detach(pid)
				#$child_pids << pid
			else
				@msgdialog.error_dialog("epsファイルが存在しません:\n\"#{@epsfile}\"")
			end
		end
		#}}}

		# png出力設定部 {{{
		frame_pngfile = Gtk::Frame.new("png出力")
		vbox_contents.pack_start(frame_pngfile,false,false,0)

		hbox_pngfile = Gtk::HBox.new(false,0)
		hbox_pngfile.border_width = 5
		frame_pngfile.add(hbox_pngfile)

		hbox_pngfile.pack_start(Gtk::Label.new("ファイルパス : "),false,false,0)
		@entry_pngfile = Gtk::Entry.new
		@entry_pngfile.text = @pngfile
		hbox_pngfile.pack_start(@entry_pngfile,true,true,0)
		## pngファイル参照ボタン
		button_pngfile = FileChooserButton2.new("SAVE",nil,"png出力")
		hbox_pngfile.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_pngfile.pack_end(button_pngfile,false,false,0)

		filter_all = Gtk::FileFilter.new.add_pattern("*")
		filter_all.name = ("All Files (*)")
		button_pngfile.dialog.add_filter(filter_all)
		filter_png = Gtk::FileFilter.new.add_pattern("*.png")
		filter_png.name = ("*.png")
		button_pngfile.dialog.add_filter(filter_png)
		button_pngfile.dialog.filter = filter_png

		## pngファイルパス変更時
		@entry_pngfile.signal_connect("changed") do |w|
			@pngfile = w.text
			#p @pngfile
			if File.directory?(@pngfile) then
				button_pngfile.current_folder = @pngfile
			elsif File.directory?(File.dirname(@pngfile)) then
				button_pngfile.current_folder = File.dirname(@pngfile)
			end
		end
		## pngファイル閲覧ボタン
		button_pngfile_view = Gtk::Button.new("閲覧...")
		hbox_pngfile.pack_end(button_pngfile_view,false,false,0)
		#hbox_pngfile.pack_end(Gtk::Label.new(""),false,false,5) # 空白
		button_pngfile_view.signal_connect("clicked") do
			#p @pngfile
			#p @option.cmd_pngview
			if File.exist?(@pngfile) then
				pid = fork{
					exec(@option.cmd_pngview+' "'+@pngfile+'"')
				}
				Process.detach(pid)
				#$child_pids << pid
			else
				@msgdialog.error_dialog("pngファイルが存在しません:\n\"#{@pngfile}\"")
			end
		end
		#}}}

		# コールバック設定 {{{
		## データファイル参照ボタンが押された時のコールバック
		cb_datafile = Proc.new do |file|
			@datafile = file
			@entry_datafile.text = (@datafile)
			@entry_datafile.position = -1
			#p @datafile
			data_dirname = File.dirname(@datafile)
			data_basename = File.basename(@datafile,File.extname(@datafile))
			# スクリプト出力パス自動変更
			@gpfile = File.join(data_dirname,data_basename) + ".gp"
			@entry_gpfile.text = @gpfile
			@entry_gpfile.position = -1
			#p @gpfile
			# eps出力パス自動変更
			@epsfile = File.join(data_dirname,data_basename) + ".eps"
			@entry_epsfile.text = @epsfile
			@entry_epsfile.position = -1
			#p @epsfile
			# png出力パス自動変更
			@pngfile = File.join(data_dirname,data_basename) + ".png"
			@entry_pngfile.text = @pngfile
			@entry_pngfile.position = -1
			#p @pngfile
			# カレントディレクトリ変更
			button_datafile.current_folder = data_dirname
			button_gpfile.current_folder = data_dirname
			button_epsfile.current_folder = data_dirname
			button_pngfile.current_folder = data_dirname
		end
		button_datafile.set_callback(cb_datafile)

		## gpファイル参照ボタンが押された時のコールバック
		cb_gpfile = Proc.new do |file|
			@gpfile = file
			gp_dirname = File.dirname(@gpfile)
			@entry_gpfile.text = @gpfile
			@entry_gpfile.position = -1
			#p @gpfile
			button_gpfile.current_folder = gp_dirname
		end
		button_gpfile.set_callback(cb_gpfile)

		## epsファイル参照ボタンが押された時のコールバック
		cb_epsfile = Proc.new do |file|
			@epsfile = file
			eps_dirname = File.dirname(@epsfile)
			eps_basename = File.basename(@epsfile,File.extname(@epsfile))
			@entry_epsfile.text = @epsfile
			@entry_epsfile.position = -1
			#p @epsfile
			button_epsfile.current_folder = eps_dirname
			# png出力パス自動変更
			@pngfile = File.join(eps_dirname,eps_basename) + ".png"
			@entry_pngfile.text = @pngfile
			@entry_pngfile.position = -1
			button_pngfile.current_folder = eps_dirname
		end
		button_epsfile.set_callback(cb_epsfile)

		## pngファイル参照ボタンが押された時のコールバック
		cb_pngfile = Proc.new do |file|
			@pngfile = file
			png_dirname = File.dirname(@pngfile)
			@entry_pngfile.text = @pngfile
			@entry_pngfile.position = -1
			#p @pngfile
			button_pngfile.current_folder = png_dirname
		end
		button_pngfile.set_callback(cb_pngfile)

		#}}}

		return vbox_contents
	end #}}}

	def get_page
		self.pack_start(get_page_general(),true,true,0)
	end

	# デフォルト値セット
	def set_defaults(option) #{{{
		@msgdialog     = MessageDialog.new # メッセージダイアログ
		@option        = option            # OptionDialogインスタンス
		@datafile      = ""                # 読込データファイルパス
		@separator     = "whitespace"      # データ区切り文字
		@commentschars = "#!%;"            # コメント開始文字
		@epsfile       = "eps_file.eps"    # eps出力ファイルパス
		@pngfile       = "png_file.png"    # eps出力ファイルパス
		@gpfile        = "tmp.gp"          # 一時ファイルパス
	end #}}}

	def initialize(option)
		super()
		set_defaults(option)
	end
	attr_reader :datafile, :separator, :commentschars, :epsfile,
		:pngfile, :gpfile

	# インスタンス変数セット関数群{{{
	def datafile=(val)
		@datafile = val
		@entry_datafile.text = @datafile
		@entry_datafile.position = -1
	end

	def separator=(val)
		@separator = val
		@radio_separator_group.each do |r|
			r.active = true if @hash_separator_value[r] == @separator
		end
	end

	def commentschars=(val)
		@commentschars = val
		@entry_commentschars.text = @commentschars
		@entry_commentschars.position = -1
	end

	def epsfile=(val)
		@epsfile = val
		@entry_epsfile.text = @epsfile
		@entry_epsfile.position = -1
	end

	def pngfile=(val)
		@pngfile = val
		@entry_pngfile.text = @pngfile
		@entry_pngfile.position = -1
	end

	def gpfile=(val)
		@gpfile = val
		@entry_gpfile.text = @gpfile
		@entry_gpfile.position = -1
	end
	#インスタンス変数セット関数群ここまで}}}

end #}}}

# 系列設定ページクラス
# VBoxのサブクラス
class PageSeries < Gtk::VBox #{{{
	def get_page_series #{{{
		# 全体の格納ボックス
		vbox_contents = Gtk::VBox.new(false,5)
		vbox_contents.border_width = 10

		frame_plotseries = Gtk::Frame.new("プロットするデータ系列")
		vbox_contents.pack_start(frame_plotseries,true,true,0)

		vbox_plotseries = Gtk::VBox.new(false,5)
		vbox_plotseries.border_width = 5
		frame_plotseries.add(vbox_plotseries)

		# プロット系列のデータ格納ボックス
		scrwin_plotseries = Gtk::ScrolledWindow.new
		scrwin_plotseries.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
		scrwin_plotseries.width_request = 830
		#scrwin_plotseries.border_width = 10
		#scrwin_plotseries.shadow_type = Gtk::SHADOW_NONE
		vbox_plotseries_plots = Gtk::VBox.new(false,5)
		vbox_plotseries_plots.border_width = 10
		vbox_plotseries.pack_start(scrwin_plotseries,true,true,0)
		scrwin_plotseries.add_with_viewport(vbox_plotseries_plots)

		#if @plot_series.length > 0 then
		#	@plot_series.each do |s|
		#		vbox_plotseries_plots.pack_start(s,false,false,0)
		#	end
		#	@plot_series = vbox_plotseries_plots
		#else
		s = PlotSeries.new(@option,vbox_plotseries_plots,"top")
		@plot_series = vbox_plotseries_plots
		vbox_plotseries_plots.pack_start(s,false,false,0)
		s.update_updown
		#end

		# 系列の追加ボタン
		#ps_count = 1
		hbox_button_add = Gtk::HBox.new(false,0)
		button_add = Gtk::Button.new("追加")
		hbox_button_add.pack_start(button_add,true,false,0)
		vbox_plotseries.pack_end(hbox_button_add,false,false,0)

		button_add.signal_connect("clicked") do
			ps_y_rows = []
			s = PlotSeries.new(@option,vbox_plotseries_plots,"bottom")
			@plot_series = vbox_plotseries_plots
			#s.linecolor = array_colorset[ps_count%11]
			#s.update_linecolor
			s.x_expr   = @x_expr_def   if @settoall_x_expr_active
			s.y_expr   = @y_expr_def   if @settoall_y_expr_active
			s.linestyle = @linestyle_def if @settoall_linestyle_active
			s.linewidth = @linewidth_def if @settoall_linewidth_active
			vbox_plotseries_plots.pack_start(s,false,false,0)
			vbox_plotseries_plots.show_all
			@plot_series.each do |ps|
				#p ps.x_row
				ps_y_rows << ps.y_row
				ps.update_updown
			end
			s.y_row = ps_y_rows.max + 1 if ps_y_rows.length > 1
			#ps_count += 1
		end

		# 値のセット用ボタン格納ボックス
		hbox_setbutton = Gtk::HBox.new(false,5)
		vbox_contents.pack_end(hbox_setbutton,false,false,0)


		# 全体に適用するフレーム
		frame_settoall = Gtk::Frame.new("全体に適用")
		hbox_setbutton.pack_start(frame_settoall,false,false,0)

		vbox_settoall = Gtk::VBox.new(false,5)
		frame_settoall.add(vbox_settoall)
		vbox_settoall.border_width = 5

		## 1行目
		### ポイントサイズ
		hbox_pointsize = Gtk::HBox.new(false,0)
		vbox_settoall.pack_start(hbox_pointsize,false,false,0)
		adj_pointsize = Gtk::Adjustment.new(1.5, 0.5, 9.5, 0.5, 0.5, 0)
		@spinner_pointsize = Gtk::SpinButton.new(adj_pointsize, 0.0, 1)
		@spinner_pointsize.wrap = false
		#vbox2.pack_start(@spinner_pointsize, false, true, 0)
		### デフォルト値セット
		@spinner_pointsize.value = @pointsize
		@spinner_pointsize.width_request = 45
		#hbox_settoall.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_pointsize.pack_start(Gtk::Label.new("ポイントサイズ : "),false,false,0)
		hbox_pointsize.pack_start(@spinner_pointsize,false,false,0)
		### ポイントサイズ変更時
		@spinner_pointsize.signal_connect("value_changed") do |w|
				@pointsize = w.value
				#p @pointsize = w.value
		end

		## 2行目
		hbox_settoall = Gtk::HBox.new(false,0)
		vbox_settoall.pack_start(hbox_settoall,false,false,0)
		#hbox_settoall.border_width = 5

		# Xプロット式
		@check_x_expr = Gtk::CheckButton.new()
		vbox_check_x_expr = Gtk::VBox.new(false,0)
		vbox_check_x_expr.pack_end(@check_x_expr,false,false,4)
		hbox_settoall.pack_start(vbox_check_x_expr,false,false,0)
		hbox_x_expr = Gtk::HBox.new(false,0)
		#hbox_x_expr.border_width = 5
		hbox_settoall.pack_start(hbox_x_expr,false,false,0)

		#hbox_x_expr.pack_start(Gtk::Label.new(""),false,false,3) # 空白
		vbox_x_expr = Gtk::VBox.new(false,0)
		vbox_x_expr.sensitive = @settoall_x_expr_active
		hbox_settoall.pack_start(vbox_x_expr,false,false,0)
		vbox_x_expr.pack_start(Gtk::Label.new.set_markup("<small>Xプロット式</small>"),false,false,0)
		@entry_x_expr = Gtk::Entry.new
		### デフォルト値セット
		@entry_x_expr.text = @x_expr_def
		@entry_x_expr.width_request = 100
		vbox_x_expr.pack_end(@entry_x_expr,false,false,0)
		### 追加式変更時
		@entry_x_expr.signal_connect("changed") do |w|
			@x_expr_def = w.text
			#p @x_expr_def
			@plot_series.each do |ps|
				ps.x_expr   = @x_expr_def   #if @settoall_x_expr_active
			end
		end
		### Xプロット式有効/無効切り替え
		@check_x_expr.active = @settoall_x_expr_active
		@check_x_expr.signal_connect("toggled") do |c|
			@settoall_x_expr_active = c.active?
			vbox_x_expr.sensitive = @settoall_x_expr_active
			@plot_series.each do |ps|
				ps.x_expr   = @x_expr_def   if @settoall_x_expr_active
			end
		end

		# Yプロット式
		@check_y_expr = Gtk::CheckButton.new()
		vbox_check_y_expr = Gtk::VBox.new(false,0)
		vbox_check_y_expr.pack_end(@check_y_expr,false,false,4)
		hbox_settoall.pack_start(vbox_check_y_expr,false,false,0)
		hbox_y_expr = Gtk::HBox.new(false,0)
		#hbox_y_expr.border_width = 5
		hbox_settoall.pack_start(hbox_y_expr,false,false,0)

		#hbox_y_expr.pack_start(Gtk::Label.new(""),false,false,3) # 空白
		vbox_y_expr = Gtk::VBox.new(false,0)
		vbox_y_expr.sensitive = @settoall_y_expr_active
		hbox_settoall.pack_start(vbox_y_expr,false,false,0)
		vbox_y_expr.pack_start(Gtk::Label.new.set_markup("<small>Yプロット式</small>"),false,false,0)
		@entry_y_expr = Gtk::Entry.new
		### デフォルト値セット
		@entry_y_expr.text = @y_expr_def
		@entry_y_expr.width_request = 100
		vbox_y_expr.pack_end(@entry_y_expr,false,false,0)
		### 追加式変更時
		@entry_y_expr.signal_connect("changed") do |w|
			@y_expr_def = w.text
			#p @y_expr_def
			@plot_series.each do |ps|
				ps.y_expr   = @y_expr_def   #if @settoall_y_expr_active
			end
		end
		### Yプロット式有効/無効切り替え
		@check_y_expr.active = @settoall_y_expr_active
		@check_y_expr.signal_connect("toggled") do |c|
			@settoall_y_expr_active = c.active?
			vbox_y_expr.sensitive = @settoall_y_expr_active
			@plot_series.each do |ps|
				ps.y_expr   = @y_expr_def   if @settoall_y_expr_active
			end
		end


		## プロットスタイル
		@check_linestyle = Gtk::CheckButton.new()
		hbox_linestyle = Gtk::HBox.new(false,0)
		vbox_linestyle = Gtk::VBox.new(false,0)
		vbox_linestyle.pack_end(hbox_linestyle,false,false,0)
		hbox_settoall.pack_start(vbox_linestyle,false,false,0)
		hbox_linestyle.pack_start(@check_linestyle,false,false,0)
		# コールバック
		cb_style = Proc.new do |*d|
			@linestyle_def = d[0]
			#p @linestyle_def
			@plot_series.each do |ps|
				ps.linestyle = @linestyle_def #if @settoall_linestyle_active
			end
		end
		### メニューアイテム
		menu_items_style = [
			["/線のみ",Gtk::ItemFactory::ITEM,nil,nil,cb_style,"lines"],
			["/線とポイント",Gtk::ItemFactory::ITEM,nil,nil,cb_style,"linespoints"],
			["/ポイントのみ",Gtk::ItemFactory::ITEM,nil,nil,cb_style,"points"],
		]
		item_factory = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_MENU, "<style>", nil)
		item_factory.create_items(menu_items_style)
		@opt_style = Gtk::OptionMenu.new
		@opt_style.menu = item_factory.get_widget("<style>")
		hbox_opt_linestyle = Gtk::HBox.new(false,0)
		hbox_linestyle.pack_start(hbox_opt_linestyle,false,false,0)
		hbox_opt_linestyle.pack_start(Gtk::Label.new("スタイル : "),false,false,0)
		hbox_opt_linestyle.pack_start(@opt_style,false,false,0)
		### デフォルト値セット
		hbox_opt_linestyle.sensitive = @settoall_linestyle_active
		case @linestyle_def
		when "lines"
			@opt_style.history = 0
		when "linespoints"
			@opt_style.history = 1
		when "points"
			@opt_style.history = 2
		end
		### プロットスタイル有効/無効切り替え
		@check_linestyle.active = @settoall_linestyle_active
		@check_linestyle.signal_connect("toggled") do |c|
			@settoall_linestyle_active = c.active?
			hbox_opt_linestyle.sensitive = @settoall_linestyle_active
			@plot_series.each do |ps|
				ps.linestyle = @linestyle_def if @settoall_linestyle_active
			end
		end


		# 線幅
		@check_linewidth = Gtk::CheckButton.new()
		hbox_linewidth = Gtk::HBox.new(false,0)
		vbox_linewidth = Gtk::VBox.new(false,0)
		vbox_linewidth.pack_end(hbox_linewidth,false,false,0)
		hbox_settoall.pack_start(vbox_linewidth,false,false,0)
		hbox_linewidth.pack_start(@check_linewidth,false,false,0)
		@adj_linewidth = Gtk::Adjustment.new(2, 1, 20, 1, 1, 0)
		spinner_linewidth = Gtk::SpinButton.new(@adj_linewidth, 0.0, 0)
		spinner_linewidth.wrap = false
		## デフォルト値セット
		spinner_linewidth.value = @linewidth_def
		spinner_linewidth.width_request = 40
		hbox_spn_linewidth = Gtk::HBox.new(false,0)
		hbox_spn_linewidth.sensitive = @settoall_linewidth_active
		hbox_linewidth.pack_start(hbox_spn_linewidth,false,false,0)
		#hbox_spn_linewidth.pack_start(Gtk::Label.new(""),false,false,2.5) # 空白
		hbox_spn_linewidth.pack_start(Gtk::Label.new("線幅 : "),false,false,0)
		hbox_spn_linewidth.pack_start(spinner_linewidth,false,false,0)
		## 線幅変更時
		spinner_linewidth.signal_connect("value_changed") do |w|
			@linewidth_def = w.value_as_int
			#p @linewidth_def = w.value_as_int
			@plot_series.each do |ps|
				ps.linewidth = @linewidth_def #if @settoall_linewidth_active
			end
		end
		### 線幅有効/無効切り替え
		@check_linewidth.active = @settoall_linewidth_active
		@check_linewidth.signal_connect("toggled") do |c|
			@settoall_linewidth_active = c.active?
			hbox_spn_linewidth.sensitive = @settoall_linewidth_active
			@plot_series.each do |ps|
				ps.linewidth = @linewidth_def if @settoall_linewidth_active
			end
		end


		## 適用ボタン ## 現在無効。値変更時に直接反映。
		#vbox_applybutton = Gtk::VBox.new(false,0)
		#hbox_settoall.pack_start(Gtk::Label.new(""),false,false,2.5) # 空白
		#hbox_settoall.pack_start(vbox_applybutton,false,false,0)
		#button_settoall = Gtk::Button.new("適用")
		#vbox_applybutton.pack_start(button_settoall,false,false,0)
		#button_settoall.signal_connect("clicked") do
		#	@plot_series.each do |ps|
		#		ps.x_expr   = @x_expr_def   if @settoall_x_expr_active
		#		ps.y_expr   = @y_expr_def   if @settoall_y_expr_active
		#		ps.linestyle = @linestyle_def if @settoall_linestyle_active
		#		ps.linewidth = @linewidth_def if @settoall_linewidth_active
		#	end
		#end

		## デフォルトにセットするボタン群を格納するbox
		hbox_defaultset = Gtk::HBox.new(false,0)
		hbox_setbutton.pack_end(hbox_defaultset,false,false,0)
		vbox_defaultset = Gtk::VBox.new(false,0)
		hbox_defaultset.pack_start(vbox_defaultset,false,false,0)

		## デフォルトの色をセットするボタン
		button_colorset = Gtk::Button.new("色順をリセット")
		vbox_defaultset.pack_end(button_colorset,false,false,0)
		button_colorset.signal_connect("clicked") do
			tmp_i = 0
			@plot_series.each do |ps|
				#p ps.x_row
				ps.linecolor = ps.linecolor_order[tmp_i%11]
				#ps.update_linecolor
				tmp_i += 1
			end
		end
		button_colorset.sensitive = !@option.flag_gp_old_ver

		## デフォルトのポイントをセットするボタン
		button_pointset = Gtk::Button.new("ポイント順をリセット")
		vbox_defaultset.pack_end(button_pointset,false,false,0)
		button_pointset.signal_connect("clicked") do
			tmp_i = 0
			@plot_series.each do |ps|
				#p ps.x_row
				ps.pointtype = ps.pointtype_order[tmp_i%11]
				#ps.update_linecolor
				tmp_i += 1
			end
		end

		return vbox_contents
	end #}}}

	def get_page
		self.pack_start(get_page_series(),true,true,0)
	end

	def set_defaults
		@plot_series               = []             # データ系列
		@x_expr_def                = "x*1e0"
		@y_expr_def                = "y*1e0"
		@linestyle_def             = "linespoints"
		@linewidth_def             = 3
		@settoall_x_expr_active    = false
		@settoall_y_expr_active    = false
		@settoall_linestyle_active = false
		@settoall_linewidth_active = false
		@pointsize                 = 1.5
	end

	def initialize(option)
		super()
		set_defaults()
		@option = option
	end
	attr_accessor :plot_series
	attr_reader :pointsize, :x_expr_def, :y_expr_def, :linestyle_def,
		:linewidth_def, :settoall_x_expr_active, :settoall_y_expr_active,
		:settoall_linestyle_active, :settoall_linewidth_active

	# インスタンス変数セットメソッド群{{{
	def pointsize=(val)
		@pointsize = val
		@spinner_pointsize.value = @pointsize
	end

	def x_expr_def=(val)
		@x_expr_def = val
		@entry_x_expr.text = @x_expr_def
	end

	def y_expr_def=(val)
		@y_expr_def = val
		@entry_y_expr.text = @y_expr_def
	end

	def linestyle_def=(val)
		@linestyle_def = val
		case @linestyle_def
		when "lines"
			@opt_style.history = 0
		when "linespoints"
			@opt_style.history = 1
		when "points"
			@opt_style.history = 2
		end
	end

	def linewidth_def=(val)
		@linewidth_def = val
		@adj_linewidth.value = @linewidth_def
	end

	def settoall_x_expr_active=(val)
		@settoall_x_expr_active = val
		@check_x_expr.active = @settoall_x_expr_active
	end

	def settoall_y_expr_active=(val)
		@settoall_y_expr_active = val
		@check_y_expr.active = @settoall_y_expr_active
	end

	def settoall_linestyle_active=(val)
		@settoall_linestyle_active = val
		@check_linestyle.active = @settoall_linestyle_active
	end

	def settoall_linewidth_active=(val)
		@settoall_linewidth_active = val
		@check_linewidth.active = @settoall_linewidth_active
	end

	# インスタンス変数セットメソッド群ここまで}}}

end #}}}

# 軸設定ページクラス
# VBoxのサブクラス
class PageAxis < Gtk::VBox #{{{
	###############################
	# 軸設定ページを作る
	# ボックスを返す
	def get_page_axis #{{{
		# 全体の格納ボックス
		vbox_contents = Gtk::VBox.new(false,10)
		vbox_contents.border_width = 10

		vbox_axis = Gtk::VBox.new(false,10)

		vbox_contents.pack_start(vbox_axis,false,false,0)

		## ラベル
		frame_label = Gtk::Frame.new("ラベル(軸のタイトル)")
		vbox_axis.pack_start(frame_label,false,false,0)

		hbox_label = Gtk::HBox.new(false,0)
		hbox_label.border_width = 7
		frame_label.add(hbox_label)

		hbox_label.pack_start(Gtk::Label.new("ラベル : "),false,false,0)
		@entry_label = Gtk::Entry.new
		### デフォルト値セット
		@entry_label.text = @label
		hbox_label.pack_start(@entry_label,true,true,0)
		### ラベル変更時
		@entry_label.signal_connect("changed") do |w|
			@label = w.text
			#p @label
		end

		### ラベル位置調整
		@adj_label_offset = Gtk::Adjustment.new(0.0, -5.0, 5.0, 0.5, 0.5, 0)
		@spinner_label_offset = Gtk::SpinButton.new(@adj_label_offset, 0.0, 1)
		@spinner_label_offset.wrap = true
		#vbox2.pack_start(@spinner_label_offset, false, true, 0)
		### デフォルト値セット
		@spinner_label_offset.value = @label_offset
		@spinner_label_offset.width_request = 50
		hbox_label.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_label.pack_start(Gtk::Label.new("位置調整 : "),false,false,0)
		hbox_label.pack_start(@spinner_label_offset,false,false,0)
		hbox_label.pack_start(Gtk::Label.new(" 文字分外側へ"),false,false,0)
		### ラベル位置調整変更時
		@spinner_label_offset.signal_connect("value_changed") do |w|
				@label_offset = w.value
				#p @label_offset = w.value
		end

		### ラベルフォントサイズ
		@entry_label_fontsize = Gtk::Entry.new
		### デフォルト値セット
		@entry_label_fontsize.text = @label_fontsize
		@entry_label_fontsize.width_request = 30
		hbox_label.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_label.pack_start(Gtk::Label.new("フォントサイズ : "),false,false,0)
		hbox_label.pack_start(@entry_label_fontsize,false,false,0)
		### フォントサイズ変更時
		@entry_label_fontsize.signal_connect("changed") do |w|
			@label_fontsize = w.text
			#p @label_fontsize
		end

		# 設定部
		## スケール（線形/対数）
		frame_scale = Gtk::Frame.new("スケール")
		vbox_axis.pack_start(frame_scale,false,false,0)

		hbox_scale = Gtk::HBox.new(false,0)
		hbox_scale.border_width = 5
		frame_scale.add(hbox_scale)

		radio_scale_lin = Gtk::RadioButton.new("線形")
		radio_scale_log = Gtk::RadioButton.new(radio_scale_lin,"対数")
		hbox_scale.pack_start(radio_scale_lin,false,false,10)
		hbox_scale.pack_start(radio_scale_log,false,false,10)

		### ボタンと値の対応
		@hash_scale_value = {
			radio_scale_lin => "lin",
			radio_scale_log => "log",
		}

		### デフォルト値セット
		@radio_scale_group = radio_scale_lin.group
		@radio_scale_group.each do |r|
			r.active = true if @hash_scale_value[r] == @scale
		end

		### スケール変更時
		@radio_scale_group.each do |r|
			r.signal_connect("toggled") do
				@scale = @hash_scale_value[r]
				#p @scale
			end
		end

		## 数値表示形式
		frame_format = Gtk::Frame.new("数値表示形式")
		vbox_axis.pack_start(frame_format,false,false,0)

		vbox_format = Gtk::VBox.new(false,5)
		vbox_format.border_width = 5
		frame_format.add(vbox_format)

		### 表示形式 1列目
		hbox_format1 = Gtk::HBox.new(false,0)
		hbox_format1.border_width = 0
		vbox_format.pack_start(hbox_format1,false,false,0)

		### 小数/小数+指数
		radio_format_float = Gtk::RadioButton.new("小数のみ")
		radio_format_exponent = Gtk::RadioButton.new(radio_format_float,"指数のみ")
		radio_format_fltexp = Gtk::RadioButton.new(radio_format_float,"小数+指数")
		radio_format_auto = Gtk::RadioButton.new(radio_format_float,"自動")

		hbox_format1.pack_start(radio_format_auto,false,false,10)
		hbox_format1.pack_start(radio_format_float,false,false,10)
		hbox_format1.pack_start(radio_format_exponent,false,false,10)
		hbox_format1.pack_start(radio_format_fltexp,false,false,10)

		### ボタンと値の対応
		@hash_format_value = {
			radio_format_auto => "auto",
			radio_format_float => "float",
			radio_format_exponent => "exponent",
			radio_format_fltexp => "fltexp",
		}

		### デフォルト値セット
		@radio_format_group = radio_format_float.group
		@radio_format_group.each do |r|
			r.active = true if @hash_format_value[r] == @format_exp
		end

		### 表示形式変更時の動作
		@radio_format_group.each do |r|
			r.signal_connect("toggled") do
				@format_exp = @hash_format_value[r]
				#p @format_exp
			end
		end

		### 表示形式 2列目
		hbox_format2 = Gtk::HBox.new(false,0)
		hbox_format2.border_width = 0
		vbox_format.pack_start(hbox_format2,false,false,0)

		### 少数点以下の桁
		adj_digits_adp = Gtk::Adjustment.new(2, 0, 5, 1, 1, 0)
		@spinner_digits_adp = Gtk::SpinButton.new(adj_digits_adp, 0.0, 0)
		@spinner_digits_adp.wrap = true
		#vbox2.pack_start(@spinner_digits_adp, false, true, 0)
		### デフォルト値セット
		@spinner_digits_adp.value = @digits_adp
		@spinner_digits_adp.sensitive = (@format_exp != "auto" && @format_exp != "exponent")
		@spinner_digits_adp.width_request = 40
		#hbox_format2.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_format2.pack_start(Gtk::Label.new("小数点以下の桁 : "),false,false,0)
		hbox_format2.pack_start(@spinner_digits_adp,false,false,0)
		### 小数点以下の桁変更時
		@spinner_digits_adp.signal_connect("value_changed") do |w|
				@digits_adp = w.value_as_int
				#p @digits_adp = w.value_as_int
		end

		### 表示形式変更時の動作を追加
		@radio_format_group.each do |r|
			r.signal_connect("toggled") do
				@spinner_digits_adp.sensitive = (@hash_format_value[r] != "auto" && @hash_format_value[r] != "exponent")
			end
		end

		### 数値表示フォントサイズ
		@entry_format_fontsize = Gtk::Entry.new
		### デフォルト値セット
		@entry_format_fontsize.text = @format_fontsize
		@entry_format_fontsize.width_request = 30
		hbox_format2.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_format2.pack_start(Gtk::Label.new("フォントサイズ : "),false,false,0)
		hbox_format2.pack_start(@entry_format_fontsize,false,false,0)
		### フォントサイズ変更時
		@entry_format_fontsize.signal_connect("changed") do |w|
			@format_fontsize = w.text
			#p @format_fontsize
		end


		## 範囲
		frame_range = Gtk::Frame.new("範囲")
		vbox_axis.pack_start(frame_range,false,false,0)

		box_range = Gtk::HBox.new(false,5)
		box_range.border_width = 5
		frame_range.add(box_range)

		### 最小値
		hbox_min = Gtk::HBox.new(false,0)
		#hbox_min.border_width = 0
		box_range.pack_start(hbox_min,false,false,5)
		hbox_min.pack_start(Gtk::Label.new("最小値 : "),false,false,0)
		@entry_min = Gtk::Entry.new
		#### デフォルト値セット
		@entry_min.text = @min
		@entry_min.width_request = 80
		hbox_min.pack_start(@entry_min,false,false,0)
		#### 最小値変更時
		@entry_min.signal_connect("changed") do |w|
			@min = w.text
			#p @min
		end

		### 最大値
		hbox_max = Gtk::HBox.new(false,0)
		#hbox_max.border_width = 0
		box_range.pack_start(hbox_max,false,false,5)
		hbox_max.pack_start(Gtk::Label.new("最大値 : "),false,false,0)
		@entry_max = Gtk::Entry.new
		#### デフォルト値セット
		@entry_max.text = @max
		@entry_max.width_request = 80
		hbox_max.pack_start(@entry_max,false,false,0)
		#### 最大値変更時
		@entry_max.signal_connect("changed") do |w|
			@max = w.text
			#p @max
		end

		## 目盛
		frame_tics = Gtk::Frame.new("目盛")
		vbox_axis.pack_start(frame_tics,false,false,0)

		vbox_tics = Gtk::VBox.new(false,5)
		vbox_tics.border_width = 5
		frame_tics.add(vbox_tics)

		### 目盛 1列目
		hbox_tics1 = Gtk::HBox.new(false,0)
		hbox_tics1.border_width = 0
		vbox_tics.pack_start(hbox_tics1,false,false,0)

		### 目盛 2列目の宣言
		hbox_tics2 = Gtk::HBox.new(false,0)
		hbox_tics2.border_width = 0

		hbox_tics2.sensitive = @tics_manual
		### 目盛手動チェックボックス
		@check_tics_manual = Gtk::CheckButton.new("目盛を手動で振る")
		vbox_tics.pack_start(@check_tics_manual,false,false,0)
		@check_tics_manual.active = @tics_manual
		@check_tics_manual.signal_connect("toggled") do |c|
			@tics_manual = c.active?
			hbox_tics2.sensitive = @tics_manual
			#p @tics_manual
		end

		### 目盛 2列目の開始
		vbox_tics.pack_start(hbox_tics2,false,false,0)
		### 目盛最小値
		hbox_tics_min = Gtk::HBox.new(false,0)
		#hbox_tics_min.border_width = 0
		hbox_tics2.pack_start(hbox_tics_min,false,false,5)
		hbox_tics_min.pack_start(Gtk::Label.new("最小値 : "),false,false,0)
		@entry_tics_min = Gtk::Entry.new
		#### デフォルト値セット
		@entry_tics_min.text = @tics_min
		@entry_tics_min.width_request = 80
		hbox_tics_min.pack_start(@entry_tics_min,false,false,0)
		#### 最小値変更時
		@entry_tics_min.signal_connect("changed") do |w|
			@tics_min = w.text
			#p @tics_min
		end

		### 目盛最大値
		hbox_tics_max = Gtk::HBox.new(false,0)
		#hbox_tics_max.border_width = 0
		hbox_tics2.pack_start(hbox_tics_max,false,false,5)
		hbox_tics_max.pack_start(Gtk::Label.new("最大値 : "),false,false,0)
		@entry_tics_max = Gtk::Entry.new
		#### デフォルト値セット
		@entry_tics_max.text = @tics_max
		@entry_tics_max.width_request = 80
		hbox_tics_max.pack_start(@entry_tics_max,false,false,0)
		#### 最小値変更時
		@entry_tics_max.signal_connect("changed") do |w|
			@tics_max = w.text
			#p @tics_max
		end

		### 目盛間隔
		hbox_tics_step = Gtk::HBox.new(false,0)
		#hbox_tics_step.border_width = 0
		hbox_tics2.pack_start(hbox_tics_step,false,false,5)
		hbox_tics_step.pack_start(Gtk::Label.new("間隔 : "),false,false,0)
		@entry_tics_step = Gtk::Entry.new
		#### デフォルト値セット
		@entry_tics_step.text = @tics_step
		@entry_tics_step.width_request = 80
		hbox_tics_step.pack_start(@entry_tics_step,false,false,0)
		#### 最小値変更時
		@entry_tics_step.signal_connect("changed") do |w|
			@tics_step = w.text
			#p @tics_step
		end

		### 目盛 3列目
		hbox_tics3 = Gtk::HBox.new(false,0)
		hbox_tics3.border_width = 0
		vbox_tics.pack_start(hbox_tics3,false,false,0)

		### 目盛 4列目の宣言
		hbox_tics4 = Gtk::HBox.new(false,0)
		hbox_tics4.border_width = 0

		hbox_tics4.sensitive = @mtics_manual
		### 小目盛手動チェックボックス
		@check_mtics_manual = Gtk::CheckButton.new("小目盛を手動で振る")
		vbox_tics.pack_start(@check_mtics_manual,false,false,0)
		@check_mtics_manual.active = @mtics_manual
		@check_mtics_manual.signal_connect("toggled") do |c|
			@mtics_manual = c.active?
			hbox_tics4.sensitive = @mtics_manual
			#p @mtics_manual
		end

		### 目盛 4列目の開始
		vbox_tics.pack_start(hbox_tics4,false,false,0)
		### 小目盛による大目盛分割数
		hbox_mtics_freq = Gtk::HBox.new(false,0)
		#hbox_mtics_freq.border_width = 0
		hbox_tics4.pack_start(hbox_mtics_freq,false,false,5)
		adj_mtics_freq = Gtk::Adjustment.new(5, 1, 10, 1, 1, 0)
		@spinner_mtics_freq = Gtk::SpinButton.new(adj_mtics_freq, 0.0, 0)
		@spinner_mtics_freq.wrap = true
		#vbox2.pack_start(@spinner_mtics_freq, false, true, 0)
		### デフォルト値セット
		@spinner_mtics_freq.value = @mtics_freq
		@spinner_mtics_freq.width_request = 40
		#hbox_format2.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_mtics_freq.pack_start(Gtk::Label.new("小目盛で目盛を"),false,false,0)
		hbox_mtics_freq.pack_start(@spinner_mtics_freq,false,false,5)
		hbox_mtics_freq.pack_start(Gtk::Label.new("分割する"),false,false,0)
		### 小目盛による大目盛分割数変更時
		@spinner_mtics_freq.signal_connect("value_changed") do |w|
				@mtics_freq = w.value_as_int
				#p @mtics_freq = w.value_as_int
		end


		## グリッド表示/非表示チェックボックス
		hbox_grid = Gtk::HBox.new(false,5)
		vbox_axis.pack_start(hbox_grid,false,false,0)
		@check_grid_show = Gtk::CheckButton.new("グリッドを表示")
		hbox_grid.pack_start(@check_grid_show,false,false,0)
		@check_grid_show.active = @grid_show
		@check_grid_show.signal_connect("toggled") do |c|
			@grid_show = c.active?
			#p @grid_show
		end

		### 小目盛グリッド
		@check_mgrid_show = Gtk::CheckButton.new("小目盛グリッド")
		hbox_grid.pack_start(@check_mgrid_show,false,false,0)
		@check_mgrid_show.active = @mgrid_show
		@check_mgrid_show.signal_connect("toggled") do |c|
			@mgrid_show = c.active?
			#p @mgrid_show
		end
		### 小目盛グリッドの有効/無効切り替え
		@check_grid_show.signal_connect("toggled") do |c|
			@check_mgrid_show.sensitive = c.active?
		end

		return vbox_contents
	end
	#}}}

	def get_page
		self.pack_start(get_page_axis(),true,true,0)
	end

	# デフォルト値セット
	def set_defaults() #{{{
		@label           = "label"   # 軸ラベル
		@label_offset    = 0         # 軸ラベルのオフセット
		@label_fontsize  = "26"      # 軸ラベルフォントサイズ
		@scale           = "lin"     # 軸スケール（線形/対数）
		@format_exp      = "auto"    # 数値表示
		@digits_adp      = 1         # 小数点以下の桁
		@format_fontsize = "26"      # 軸数値表示フォントサイズ
		@min             = "*"       # 軸最小値
		@max             = "*"       # 軸最大値
		@tics_manual     = false     # 目盛を手動で振るかどうか
		@tics_min        = ""        # 目盛最小値
		@tics_step       = ""        # 目盛間隔
		@tics_max        = ""        # 目盛最大値
		@mtics_manual    = false     # 小目盛を手動で振るかどうか
		@mtics_freq      = 5         # 小目盛による目盛分割数
		@grid_show       = true      # グリッドを表示するかどうか
		@mgrid_show      = false     # 小目盛グリッドを表示するかどうか
	end #}}}

	def initialize() #{{{
		super()
		set_defaults()
	end #}}}
	attr_reader :label, :label_offset,:label_fontsize, :scale, :format_exp,
		:digits_adp, :format_fontsize, :min, :max,
		:tics_manual, :tics_min, :tics_step, :tics_max,
		:mtics_manual, :mtics_freq, :grid_show, :mgrid_show

	# インスタンス変数セット関数{{{
	def label=(val)
		@label = val
		@entry_label.text = @label
	end

	def label_offset=(val)
		@label_offset = val
		@spinner_label_offset.value = @label_offset
	end

	def label_fontsize=(val)
		@label_fontsize = val
		@entry_label_fontsize.text = @label_fontsize
	end

	def scale=(val)
		@scale = val
		@radio_scale_group.each do |r|
			r.active = true if @hash_scale_value[r] == @scale
		end
	end

	def format_exp=(val)
		@format_exp = val
		@radio_format_group.each do |r|
			r.active = true if @hash_format_value[r] == @format_exp
		end
	end

	def digits_adp=(val)
		@digits_adp = val
		@spinner_digits_adp.value = @digits_adp
	end

	def format_fontsize=(val)
		@format_fontsize = val
		@entry_format_fontsize.text = @format_fontsize
	end

	def min=(val)
		@min = val
		@entry_min.text = @min
	end

	def max=(val)
		@max = val
		@entry_max.text = @max
	end

	def tics_manual=(val)
		@tics_manual = val
		@check_tics_manual.active = @tics_manual
	end

	def tics_min=(val)
		@tics_min = val
		@entry_tics_min.text = @tics_min
	end

	def tics_step=(val)
		@tics_step = val
		@entry_tics_step.text = @tics_step
	end

	def tics_max=(val)
		@tics_max = val
		@entry_tics_max.text = @tics_max
	end

	def mtics_manual=(val)
		@mtics_manual = val
		@check_mtics_manual.active = @mtics_manual
	end

	def mtics_freq=(val)
		@mtics_freq = val
		@spinner_mtics_freq.value = @mtics_freq
	end

	def grid_show=(val)
		@grid_show = val
		@check_grid_show.active = @grid_show
	end

	def mgrid_show=(val)
		@mgrid_show = val
		@check_mgrid_show.active = @mgrid_show
	end
	# インスタンス変数セット関数ここまで}}}

end #}}}

# 凡例設定ページサブクラス
# VBoxのサブクラス
class PageLegend < Gtk::VBox #{{{
	def get_page_legend #{{{
		# 全体の格納ボックス
		vbox_contents = Gtk::VBox.new(false,5)
		vbox_contents.border_width = 10

		## 凡例表示チェック
		@check_visible = Gtk::CheckButton.new("凡例を表示する")
		vbox_contents.pack_start(@check_visible,false,false,0)
		@check_visible.active = @visible

		# 全体の格納ボックス
		vbox_contents_visible = Gtk::VBox.new(false,10)
		#vbox_contents_visible.border_width = 10
		vbox_contents.pack_start(vbox_contents_visible,false,false,0)

		## 凡例表示チェック切替時
		@check_visible.signal_connect("toggled") do |c|
			@visible = c.active?
			#p @visible
			vbox_contents_visible.sensitive = c.active?
		end

		# 位置
		frame_position = Gtk::Frame.new("位置")
		vbox_contents_visible.pack_start(frame_position,false,false,0)

		hbox_position_eg = Gtk::HBox.new(false,0)
		frame_position.add(hbox_position_eg)
		table_position_eg = Gtk::Table.new(4,4,false)
		table_position_eg.border_width = 10
		hbox_position_eg.pack_start(table_position_eg,false,false,0)
		frame_position_eg = Gtk::Frame.new
		#frame_position_eg.border_width = 0
		frame_position_eg.shadow_type = Gtk::SHADOW_ETCHED_OUT
		table_position_eg.attach_defaults(frame_position_eg,0,3,0,3)
		table_position_eg.attach_defaults(Gtk::Label.new("グラフ"),1,2,1,2)
		#table_position_eg.row_spacings = 10
		#table_position_eg.column_spacings = 10

		## 位置選択ラジオボタン
		radio_pos_lt  = Gtk::RadioButton.new("左上")
		radio_pos_lb  = Gtk::RadioButton.new(radio_pos_lt,"左下")
		radio_pos_rt  = Gtk::RadioButton.new(radio_pos_lt,"右上")
		radio_pos_rb  = Gtk::RadioButton.new(radio_pos_lt,"右下")
		radio_pos_rmt = Gtk::RadioButton.new(radio_pos_lt,"右外側の上")
		radio_pos_rmc = Gtk::RadioButton.new(radio_pos_lt,"右外側中央")
		radio_pos_rmb = Gtk::RadioButton.new(radio_pos_lt,"右外側の下")
		radio_pos_lbm  = Gtk::RadioButton.new(radio_pos_lt,"グラフ下の左")
		radio_pos_cbm  = Gtk::RadioButton.new(radio_pos_lt,"グラフ下中央")
		radio_pos_rbm  = Gtk::RadioButton.new(radio_pos_lt,"グラフ下の右")

		### ボタンと値の対応
		@hash_pos_value = {
			radio_pos_lt  => "left top",
			radio_pos_lb  => "left bottom",
			radio_pos_rt  => "right top",
			radio_pos_rb  => "right bottom",
			radio_pos_rmt => "rmargin top",
			radio_pos_rmc => "rmargin center",
			radio_pos_rmb => "rmargin bottom",
			radio_pos_lbm  => "left below",
			radio_pos_cbm  => "center below",
			radio_pos_rbm  => "right below",
		}

		### 右寄せのためのボックス
		box_pos_rt = Gtk::HBox.new(false,0)
		box_pos_rt.pack_end(radio_pos_rt,false,false,5)
		box_pos_rb = Gtk::HBox.new(false,0)
		box_pos_rb.pack_end(radio_pos_rb,false,false,5)
		box_pos_rbm = Gtk::HBox.new(false,0)
		box_pos_rbm.pack_end(radio_pos_rbm,false,false,5)

		### ラジオボタンの配置
		table_position_eg.attach_defaults(radio_pos_lt,0,1,0,1)
		table_position_eg.attach_defaults(radio_pos_lb,0,1,2,3)
		table_position_eg.attach_defaults(radio_pos_lbm,0,1,3,4)

		table_position_eg.attach_defaults(radio_pos_cbm,1,2,3,4)

		table_position_eg.attach_defaults(box_pos_rt,2,3,0,1)
		table_position_eg.attach_defaults(box_pos_rb,2,3,2,3)
		table_position_eg.attach_defaults(box_pos_rbm,2,3,3,4)

		table_position_eg.attach_defaults(radio_pos_rmt,3,4,0,1)
		table_position_eg.attach_defaults(radio_pos_rmc,3,4,1,2)
		table_position_eg.attach_defaults(radio_pos_rmb,3,4,2,3)


		### デフォルト値セット
		@radio_pos_group = radio_pos_lt.group
		@radio_pos_group.each do |r|
			r.active = true if @hash_pos_value[r] == @position
		end

		## 位置変更時
		@radio_pos_group.each do |r|
			r.signal_connect("toggled") do
				@position = @hash_pos_value[r]
				#p @position
			end
		end

		# 表示
		frame_display = Gtk::Frame.new("表示")
		vbox_contents_visible.pack_start(frame_display,false,false,0)

		vbox_display = Gtk::VBox.new(false,0)
		vbox_display.border_width = 5
		frame_display.add(vbox_display)

		## 1行目
		hbox_display1 = Gtk::HBox.new(false,5)
		vbox_display.pack_start(hbox_display1,false,false,0)

		## 揃え基準
		radio_align_left = Gtk::RadioButton.new("左揃え")
		radio_align_right = Gtk::RadioButton.new(radio_align_left,"右揃え")
		hbox_display1.pack_start(radio_align_left,false,false,0)
		hbox_display1.pack_start(radio_align_right,false,false,0)

		### ボタンと値の対応
		@hash_align_value = {
			radio_align_left => "Left",
			radio_align_right => "Right",
		}

		### デフォルト値セット
		@radio_align_group = radio_align_left.group
		@radio_align_group.each do |r|
			r.active = true if @hash_align_value[r] == @align
		end

		### 揃え基準変更時
		@radio_align_group.each do |r|
			r.signal_connect("toggled") do
				@align = @hash_align_value[r]
				#p @align
			end
		end

		## 反転チェック
		@check_reverse = Gtk::CheckButton.new("記号と説明を左右反転 (記号が左)")
		hbox_display1.pack_start(@check_reverse,false,false,10)

		@check_reverse.active = @reverse
		@check_reverse.signal_connect("toggled") do |c|
			@reverse = c.active?
			#p @reverse
		end

		## 2行目
		hbox_display2 = Gtk::HBox.new(false,0)
		hbox_display2.border_width = 5
		vbox_display.pack_start(hbox_display2,false,false,0)

		### 凡例上下間隔
		adj_spacing = Gtk::Adjustment.new(1.0, 0.0, 5.0, 0.1, 0.1, 0)
		@spinner_spacing = Gtk::SpinButton.new(adj_spacing, 0.0, 1)
		@spinner_spacing.wrap = true
		#vbox2.pack_start(@spinner_spacing, false, true, 0)
		### デフォルト値セット
		@spinner_spacing.value = @spacing
		@spinner_spacing.width_request = 45
		#hbox_display2.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_display2.pack_start(Gtk::Label.new("上下間隔 : "),false,false,0)
		hbox_display2.pack_start(@spinner_spacing,false,false,0)
		hbox_display2.pack_start(Gtk::Label.new("倍"),false,false,3)
		### 凡例上下間隔変更時
		@spinner_spacing.signal_connect("value_changed") do |w|
				@spacing = w.value
				#p @spacing = w.value
		end

		### 凡例幅調整
		adj_width = Gtk::Adjustment.new(0, -50, 50, 1, 1, 0)
		@spinner_width = Gtk::SpinButton.new(adj_width, 0.0, 0)
		@spinner_width.wrap = false
		#vbox2.pack_start(@spinner_width, false, true, 0)
		### デフォルト値セット
		@spinner_width.value = @width
		@spinner_width.width_request = 45
		hbox_display2.pack_start(Gtk::Label.new(""),false,false,10) # 空白
		hbox_display2.pack_start(Gtk::Label.new("幅調整 : "),false,false,0)
		hbox_display2.pack_start(@spinner_width,false,false,0)
		hbox_display2.pack_start(Gtk::Label.new("文字分"),false,false,3)
		### 凡例幅調整変更時
		@spinner_width.signal_connect("value_changed") do |w|
				@width = w.value_as_int
				#p @width = w.value_as_int
		end

		### フォントサイズ設定部
		hbox_fontsize = Gtk::HBox.new(false,0)
		#hbox_fontsize.border_width = 0
		hbox_display2.pack_start(Gtk::Label.new(""),false,false,10) # 空白
		hbox_display2.pack_start(hbox_fontsize,false,false,0)

		hbox_fontsize.pack_start(Gtk::Label.new("フォントサイズ : "),false,false,0)
		@entry_legend_fontsize = Gtk::Entry.new
		@entry_legend_fontsize.width_request = 30
		### デフォルト値セット
		@entry_legend_fontsize.text = @fontsize
		hbox_fontsize.pack_start(@entry_legend_fontsize,false,false,0)
		### フォントサイズ変更時
		@entry_legend_fontsize.signal_connect("changed") do |w|
			@fontsize = w.text
			#p @fontsize
		end

		return vbox_contents
	end #}}}

	def get_page
		self.pack_start(get_page_legend(),true,true,0)
	end

	def set_defaults
		@visible  = true        # 凡例を表示するかどうか
		@position = "right top" # 凡例の位置
		@align    = "Right"     # 凡例の揃え基準
		@reverse  = false       # 凡例を反転するか
		@spacing  = 1.0         # 凡例間隔(行)
		@fontsize = "20"        # 凡例フォントサイズ
		@width    = 0           # 幅調整
	end

	def initialize
		super()
		set_defaults()
	end
	attr_reader :visible, :position, :align, :reverse, :spacing, :fontsize, :width

	# インスタンス変数セット関数群 {{{
	def visible=(val)
		@visible = val
		@check_visible.active = @visible
	end

	def position=(val)
		@position = val
		@radio_pos_group.each do |r|
			r.active = true if @hash_pos_value[r] == @position
		end
	end

	def align=(val)
		@align = val
		@radio_align_group.each do |r|
			r.active = true if @hash_align_value[r] == @align
		end
	end

	def reverse=(val)
		@reverse = val
		@check_reverse.active = @reverse
	end

	def spacing=(val)
		@spacing = val
		@spinner_spacing.value = @spacing
	end

	def fontsize=(val)
		@fontsize = val
		@entry_legend_fontsize.text = @fontsize
	end

	def width=(val)
		@width = val
		@spinner_width.value = @width
	end

	# インスタンス変数セット関数群ここまで }}}

end #}}}

# その他設定ページクラス
# VBoxのサブクラス
class PageEtc < Gtk::VBox #{{{
	def get_page_etc #{{{
		vbox_contents = Gtk::VBox.new(false,10)
		vbox_contents.border_width = 10

		# 余白
		frame_margin = Gtk::Frame.new("余白")
		vbox_contents.pack_start(frame_margin,false,false,0)

		table_margin_eg = Gtk::Table.new(3,3,false)
		#table_margin_eg.border_width = 10
		hbox_margin_eg = Gtk::HBox.new(false,0)
		vbox_margin_eg = Gtk::VBox.new(false,0)
		vbox_margin_eg.border_width = 10

		hbox_margin_note = Gtk::HBox.new(false,0)
		#hbox_margin_note.border_width = 10
		#hbox_margin_note.pack_start(Gtk::Label.new("グラフ端から描画領域端までの(数値・ラベルを含む)幅\nに相当する文字数で指定"),false,false,0)
		vbox_margin_eg.pack_start(hbox_margin_note,false,false,0)
		vbox_margin_eg.pack_start(hbox_margin_eg,false,false,0)
		#frame_margin.add(table_margin_eg)
		frame_margin.add(vbox_margin_eg)
		hbox_margin_eg.pack_start(table_margin_eg,false,false,0)
		frame_margin_eg = Gtk::Frame.new
		#frame_margin_eg.border_width = 0
		frame_margin_eg.shadow_type = Gtk::SHADOW_ETCHED_OUT
		table_margin_eg.attach_defaults(frame_margin_eg,1,2,1,2)
		table_margin_eg.attach(Gtk::Label.new("グラフ"),1,2,1,2,
							  nil,nil,10,10)

		## 余白入力テキストボックス
		@entry_tmargin = Gtk::Entry.new
		@entry_bmargin = Gtk::Entry.new
		@entry_lmargin = Gtk::Entry.new
		@entry_rmargin = Gtk::Entry.new
		## デフォルト値セット
		@entry_tmargin.text = @tmargin
		@entry_bmargin.text = @bmargin
		@entry_lmargin.text = @lmargin
		@entry_rmargin.text = @rmargin

		@entry_tmargin.width_request = 25
		@entry_bmargin.width_request = 25
		@entry_lmargin.width_request = 25
		@entry_rmargin.width_request = 25

		vbox_tmargin = Gtk::VBox.new(false,0)
		vbox_bmargin = Gtk::VBox.new(false,0)
		vbox_lmargin = Gtk::VBox.new(false,0)
		vbox_rmargin = Gtk::VBox.new(false,0)

		#vbox_tmargin.pack_start(Gtk::Label.new(""),false,false,1)
		#vbox_bmargin.pack_end(Gtk::Label.new(""),false,false,1)
		vbox_lmargin.pack_start(Gtk::Label.new("　左："),false,false,1)
		vbox_rmargin.pack_start(Gtk::Label.new("　右："),false,false,1)

		hbox_tmargin_entry = Gtk::HBox.new(false,0)
		hbox_bmargin_entry = Gtk::HBox.new(false,0)
		hbox_lmargin_entry = Gtk::HBox.new(false,0)
		hbox_rmargin_entry = Gtk::HBox.new(false,0)

		hbox_tmargin_entry.pack_start(Gtk::Label.new("　上："),false,false,0)
		hbox_tmargin_entry.pack_start(@entry_tmargin,false,false,0)
		hbox_tmargin_entry.pack_start(Gtk::Label.new("文字分"),false,false,0)
		hbox_bmargin_entry.pack_start(Gtk::Label.new("　下："),false,false,0)
		hbox_bmargin_entry.pack_start(@entry_bmargin,false,false,0)
		hbox_bmargin_entry.pack_start(Gtk::Label.new("文字分"),false,false,0)
		hbox_lmargin_entry.pack_start(@entry_lmargin,true,false,0)
		hbox_rmargin_entry.pack_start(@entry_rmargin,true,false,0)

		vbox_tmargin.pack_start(hbox_tmargin_entry,false,false,1)
		vbox_bmargin.pack_start(hbox_bmargin_entry,false,false,1)
		vbox_lmargin.pack_start(hbox_lmargin_entry,false,false,1)
		vbox_rmargin.pack_start(hbox_rmargin_entry,false,false,1)

		vbox_lmargin.pack_start(Gtk::Label.new("文字分"),false,false,1)
		vbox_rmargin.pack_start(Gtk::Label.new("文字分"),false,false,1)

		table_margin_eg.attach(vbox_tmargin,1,2,0,1,Gtk::SHRINK)
		table_margin_eg.attach(vbox_bmargin,1,2,2,3,Gtk::SHRINK)
		table_margin_eg.attach_defaults(vbox_lmargin,0,1,1,2)
		table_margin_eg.attach_defaults(vbox_rmargin,2,3,1,2)

		## 余白変更時
		@entry_tmargin.signal_connect("changed") do |w|
			@tmargin = w.text
			#p @tmargin
		end
		@entry_bmargin.signal_connect("changed") do |w|
			@bmargin = w.text
			#p @bmargin
		end
		@entry_rmargin.signal_connect("changed") do |w|
			@rmargin = w.text
			#p @rmargin
		end
		@entry_lmargin.signal_connect("changed") do |w|
			@lmargin = w.text
			#p @lmargin
		end

		# アスペクト比
		frame_raito = Gtk::Frame.new("縦横比")
		vbox_contents.pack_start(frame_raito,false,false,0)
		vbox_aspect = Gtk::VBox.new(false,0)
		vbox_aspect.border_width = 10
		frame_raito.add(vbox_aspect)

		hbox_aspect1 = Gtk::HBox.new(false,0)
		vbox_aspect.pack_start(hbox_aspect1,false,false,0)
		## 縦/横の値
		@adj_aspect_x = Gtk::Adjustment.new(10, 1, 100, 1, 1, 0)
		spinner_aspect_x = Gtk::SpinButton.new(@adj_aspect_x, 0.0, 0)
		@adj_aspect_y = Gtk::Adjustment.new(7, 1, 100, 1, 1, 0)
		spinner_aspect_y = Gtk::SpinButton.new(@adj_aspect_y, 0.0, 0)
		#spinner_aspect.wrap = true
		## デフォルト値セット
		spinner_aspect_x.value = @aspect_x
		spinner_aspect_y.value = @aspect_y
		spinner_aspect_x.width_request = 45
		spinner_aspect_y.width_request = 45
		#hbox_aspect1.pack_start(Gtk::Label.new(""),false,false,5) # 空白
		hbox_aspect1.pack_start(Gtk::Label.new("横 : 縦 = "),false,false,0)
		hbox_aspect1.pack_start(spinner_aspect_x,false,false,0)
		hbox_aspect1.pack_start(Gtk::Label.new(":"),false,false,5) # 空白
		hbox_aspect1.pack_start(spinner_aspect_y,false,false,0)
		## 縦/横の値変更時
		spinner_aspect_x.signal_connect("value_changed") do |w|
				@aspect_x = w.value
				#p @aspect_x = w.value
		end
		spinner_aspect_y.signal_connect("value_changed") do |w|
				@aspect_y = w.value
				#p @aspect_y = w.value
		end

		return vbox_contents
	end #}}}

	def get_page
		self.pack_start(get_page_etc(),true,true,0)
	end

	def set_defaults
		@tmargin = ""
		@bmargin = ""
		@lmargin = ""
		@rmargin = ""
		@aspect_x   = 10
		@aspect_y   = 7
	end

	def initialize
		super()
		set_defaults()
	end
	attr_reader :tmargin, :bmargin, :lmargin, :rmargin, :aspect_x, :aspect_y

	# インスタンス変数セット関数群 {{{
	def tmargin=(var)
		@tmargin = var
		@entry_tmargin.text = @tmargin
	end

	def bmargin=(var)
		@bmargin = var
		@entry_bmargin.text = @bmargin
	end

	def lmargin=(var)
		@lmargin = var
		@entry_lmargin.text = @lmargin
	end

	def rmargin=(var)
		@rmargin = var
		@entry_rmargin.text = @rmargin
	end

	def aspect_x=(var)
		@aspect_x = var
		@adj_aspect_x.value = @aspect_x
	end

	def aspect_y=(var)
		@aspect_y = var
		@adj_aspect_y.value = @aspect_y
	end
	# インスタンス変数セット関数群ここまで }}}

end #}}}

# 処理中メッセージ表示クラス
# Hboxのサブクラス
class ProgressMessage < Gtk::HBox #{{{
	def get_contents
		self.pack_start(@message_cont,false,false,0)
	end
	def reset
		@count = 0
		@message_cont.label = @message_base
	end
	def pulse
		@count += 1
		@count -= @message_vals.length if @count == @message_vals.length
		@message_cont.label = @message_base + @message_vals[@count]
	end
	def done
		@message_cont.label = @message_norm
	end
	def initialize
		@count = 0
		@message_norm = ""
		@message_base = "処理中"
		@message_vals = ["", " .", " . .", " . . ."]
		@message_cont = Gtk::Label.new(@message_norm)
		super(false,0)
		get_contents()
	end
end #}}}

# メッセージダイアログクラス
class MessageDialog #{{{
	# 終了確認のダイアログを出す
	def quit_confirm #{{{
		d = Gtk::Dialog.new
		label = Gtk::Label.new("Really quit?")
		label.show
		d.vbox.pack_start(label,true,true,20)
		d.add_button(Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK)
		d.add_button(Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL)
		d.default_response = Gtk::Dialog::RESPONSE_CANCEL
		d.signal_connect("response") do |widget,response|
			case response
			when Gtk::Dialog::RESPONSE_OK
				#p "OK"
				self.destroy
			when Gtk::Dialog::RESPONSE_CANCEL
				#p "Cancel"
				d.destroy
			end
		end
		d.show_all
	end #}}}

	# アバウト情報のダイアログを出す
	def show_about #{{{
		d = Gtk::AboutDialog.new
		d.name = "gpgui"
		#`svn status --xml` =~ /<entry[\s\n]+path="gpgui\.rb">.*?<wc-status.*?revision="(\d+)">.*?<\/entry>/m
		#revision = $1
		d.version = "2.0beta2"
		d.authors = ["Takaaki Kasai",]
		d.copyright = "Copyright (c) 2008-2009 Takaaki Kasai"
		d.comments = "2DデータプロットのためのgnuplotGUIフロントエンド\n\nby Takaaki Kasai\n\nSpecial thanks:\nDaisuke Satoh\nYusuke Yokoyama\nKoji Toyomaru\nOn Odanaka"
		d.license = <<-EOS
Copyright (c) 2008-2009 Takaaki Kasai

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

		EOS
		d.signal_connect("response"){d.destroy}
		d.run
	end #}}}

	# メッセージダイアログ
	## 情報通知ダイアログ
	def info_dialog(str) #{{{
		d = Gtk::MessageDialog.new(nil,Gtk::Dialog::MODAL,
								   Gtk::MessageDialog::INFO,
								   Gtk::MessageDialog::BUTTONS_OK,str)
		d.show_all
		d.signal_connect("response") do
			d.destroy
		end
		return d
	end #}}}

	## エラーダイアログ
	def error_dialog(str) #{{{
		d = Gtk::MessageDialog.new(nil,Gtk::Dialog::MODAL,
								   Gtk::MessageDialog::ERROR,
								   Gtk::MessageDialog::BUTTONS_OK,str)
		d.show_all
		d.signal_connect("response") do
			d.destroy
		end
		return d
	end #}}}

	## 確認のダイアログを出す
	def confirm_dialog(message, proc_ok, proc_cancel) #{{{
		d = Gtk::Dialog.new
		label = Gtk::Label.new(message)
		label.show
		d.vbox.pack_start(label,true,true,20)
		d.add_button(Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK)
		d.add_button(Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL)
		d.default_response = Gtk::Dialog::RESPONSE_CANCEL
		d.signal_connect("response") do |widget,response|
			case response
			when Gtk::Dialog::RESPONSE_OK
				#p "OK"
				d.destroy
				proc_ok.call
			when Gtk::Dialog::RESPONSE_CANCEL
				#p "Cancel"
				d.destroy
				proc_cancel.call
			end
		end
		d.show_all
	end #}}}

	# /初期化関数
	def initialize #{{{
	end #}}}

end #}}}

# セッション機能クラス
class Session #{{{

	# セッション再開
	def load #{{{
		@dialog.current_folder = @current_folder if @current_folder
		@dialog.default_response = Gtk::Dialog::RESPONSE_ACCEPT
		filter_all = Gtk::FileFilter.new.add_pattern("*")
		filter_all.name = ("All Files (*)")
		@dialog.add_filter(filter_all)
		filter_gp = Gtk::FileFilter.new.add_pattern("*.gp")
		filter_gp.name = ("*.gp")
		@dialog.add_filter(filter_gp)
		@dialog.filter = filter_gp
		if @dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
			#puts "filename = #{@dialog.filename}"
			gp_import(@dialog.filename)
			@current_folder = @dialog.current_folder
		end
		@dialog.hide
	end #}}}

	# gpファイル読込
	def gp_import(filename) #{{{
		f = open(filename)
		gp_cont = f.read.gsub("\\\n","").gsub(/^\s*/,"").gsub(/^#(?!\%).*/,"").gsub(/^\n/,"")

		#puts gp_cont
		set_general(gp_cont,filename)
		set_series(gp_cont)
		set_style(gp_cont)
		set_axis(gp_cont,@xaxis,/x(?!2)/)
		set_axis(gp_cont,@yaxis,/y(?!2)/)
		set_axis(gp_cont,@y2axis,/y2/)
		set_legend(gp_cont)
		set_etc(gp_cont)
		#set_option(gp_cont)

	end #}}}

	# オプションファイル読込
	def option_import #{{{
		return nil unless File.exist?(@option.savefile)
		f = open(@option.savefile)
		option_cont = f.read.gsub("\\\n","").gsub(/^\s*/,"").gsub(/^#(?!\%).*/,"").gsub(/^\n/,"")

		#puts option_cont
		set_option(option_cont)

	end #}}}

	# 全般セット 
	def set_general(gp_cont,filename) #{{{
		# デフォルト値セット
		@general.datafile = ""
		@general.separator = "whitespace"
		@general.commentschars = "#"
		@general.gpfile = filename
		@general.epsfile = "eps_file.eps"
		@general.pngfile = "png_file.png"
		datafile_auto_flag = true
		gp_cont.each do |line|
			if line =~ /^\s*plot\s+(.*)/ && datafile_auto_flag then
				if $1 =~ /^"(.*?)"/ then
					@general.datafile = $1
				end
			end
			if line =~ /@general\.datafile="(.*?)"/ then
				@general.datafile = $1
				datafile_auto_flag = false
			end
			re_datafile = /dataf(?:i(?:le?)?)?/
			re_separator = /sep(?:a(?:r(?:a(?:t(?:or?)?)?)?)?)?/
			if line =~ /^\s*set?\s+#{re_datafile}\s+#{re_separator}\s+(\S+)/
				sep = $1.gsub(/"/,"")
				@general.separator = sep
			end
			re_commentschars = /com(?:m(?:e(?:n(?:t(?:s(?:c(?:h(?:a(?:rs?)?)?)?)?)?)?)?)?)?/
			if line =~ /^\s*set?\s+#{re_datafile}\s+#{re_commentschars}\s+"(.*?)"/
				@general.commentschars = $1
			end
			re_output = /o(?:u(?:t(?:p(?:ut?)?)?)?)?/
			if line =~ /^\s*set?\s+output\s+"(.*?)"/
				@general.epsfile = $1
			end
			if line =~ /@general\.pngfile="(.*?)"/ then
				@general.pngfile = $1
			end
		end
	end # }}}

	# 系列(プロット)セット
	def set_series(gp_cont) #{{{
		# デフォルト値セット
		@series.plot_series.each do |ps|
			@series.plot_series.remove(ps)
		end
		@series.x_expr_def = "x*1e0"
		@series.y_expr_def = "y*1e0"
		@series.settoall_x_expr_active = false
		@series.settoall_y_expr_active = false
		gp_cont.each do |line|
			if line =~ /^plot\s+(.*)/ then
				plots = $1
				loop do
					break unless plots.sub!(/^([^"]*("[^"]*"[^"]*)*),/,'\\1<SPLIT-HERE>')
				end
				ps = plots.split(/<SPLIT-HERE>/)
				ps.each do |plot|
					s = PlotSeries.new(@option,@series.plot_series)
					if plot =~ /^\s*"(.*?)"/ then
						s.datafile = $1
					end
					if plot =~ /(^|\s)using\s+(\d+|\(.*\))\:(\d+|\(.*\))(\s|$)/ then
						x_r = $2
						y_r = $3
					else
						x_r = "1"
						y_r = "2"
					end
					if x_r =~ /^\d+$/
						s.x_row = x_r.to_i
					elsif x_r =~ /\(\s*(.*?)\$(\d+)\s*(.*)\)/
						s.x_row = $2.to_i
						s.x_expr = $1+"x"+$3
					else
						x_r =~ /^\((.*)\)$/
						s.x_expr = $1
					end
					if y_r =~ /^\d+$/
						s.y_row = y_r.to_i
					elsif y_r =~ /\(\s*(.*?)\$(\d+)\s*(.*)\)/
						s.y_row = $2.to_i
						s.y_expr = $1+"y"+$3
					else
						y_r =~ /^\((.*)\)$/
						s.y_expr = $1
					end
					if plot =~ /(?:^|\s)ax(?:is?)?\s+x1y2/ then
						s.y2axis = true
					end
					if plot =~ /(?:^|\s)w(?:i(?:th?)?)?\s+(\S+)/ then
						s.linestyle = $1
						case $1
						when /l(?:i(?:n(?:es?)?)?)?$/ then
							#p "lines"
							s.linestyle = "lines"
						when /l(?:inesp(?:o(?:i(?:n(?:ts?)?)?)?)?|p)$/ then
							#p "linespoints"
							s.linestyle = "linespoints"
						when /p(?:o(?:i(?:n(?:ts?)?)?)?)?$/ then
							#p "points"
							s.linestyle = "points"
						end
					end
					if plot =~ /(?:^|\s)t(?:i(?:t(?:le?)?)?)?\s+"(.*?)"/ then
						s.title = $1
					elsif plot =~ /(?:^|\s)not(?:i(?:t(?:le?)?)?)?(\s|$)/ then
						s.title = ""
					end
					@series.plot_series.pack_start(s,false,false,0)
					@series.plot_series.show_all
				end
				@series.plot_series.each do |ps|
					ps.update_updown
				end
			end 
			# 全体に適用するXプロット式
			if line =~ /@series\.x_expr_def="(.*?)"/ then
				@series.x_expr_def = $1
			end
			# 全体に適用するYプロット式
			if line =~ /@series\.y_expr_def="(.*?)"/ then
				@series.y_expr_def = $1
			end
			# Xプロット式を全体に適用するかどうか
			if line =~ /@series\.settoall_x_expr_active="(.*?)"/ then
				case $1
				when "true" then
					@series.settoall_x_expr_active = true
				when "false" then
					@series.settoall_x_expr_active = false
				end
			end
			# Yプロット式を全体に適用するかどうか
			if line =~ /@series\.settoall_y_expr_active="(.*?)"/ then
				case $1
				when "true" then
					@series.settoall_y_expr_active = true
				when "false" then
					@series.settoall_y_expr_active = false
				end
			end
		end
	end #}}}

	# 系列(スタイル)セット
	def set_style(gp_cont) #{{{
		# デフォルト値セット
		@series.pointsize = 1.0
		@series.linestyle_def = "linespoints"
		@series.linewidth_def = 3
		@series.settoall_linestyle_active = false
		@series.settoall_linewidth_active = false
		array_style = gp_cont.scan(/^\s*set?\s+st(?:y(?:le?)?)?\s+l(?:i(?:ne?)?)?\s+(\d+)\s+(.*)/)
		tmp_count = 1
		@series.plot_series.each do |ps|
			if array_style.assoc(tmp_count.to_s) then
				style = array_style.assoc(tmp_count.to_s)[1]
			else
				next
			end
			if style =~ /(?:linet(?:y(?:pe?)?)?|lt)\s+(\d+)/ then
				ps.linetype = $1.to_i
			end
			if style =~ /(?:linew(?:i(?:d(?:th?)?)?)?|lw)\s+(\d+)/ then
				ps.linewidth = $1.to_i
			end
			if style =~ /(?:pointt(?:y(?:pe?)?)?|pt)\s+(\d+)/ then
				ps.pointtype = $1.to_i
			end
			if style =~ /(?:linec(?:o(?:l(?:or?)?)?)?|lc)\s+rgb\s+"(\S+)"/ then
				ps.linecolor = $1
			end
			tmp_count += 1
		end

		gp_cont.each do |line|
			# ポイントサイズ
			if line =~ /^\s*set\s+pointsize\s+(#{$re_float})/ then
				@series.pointsize = $1.to_f
			end
			# 全体に適用する線のスタイル
			if line =~ /@series\.linestyle_def="(.*?)"/ then
				@series.linestyle_def = $1
			end
			# 全体に適用する線幅
			if line =~ /@series\.linewidth_def="(.*?)"/ then
				@series.linewidth_def = $1.to_f
			end
			# 線のスタイルを全体に適用するかどうか
			if line =~ /@series\.settoall_linestyle_active="(.*?)"/ then
				case $1
				when "true" then
					@series.settoall_linestyle_active = true
				when "false" then
					@series.settoall_linestyle_active = false
				end
			end
			# 線幅を全体に適用するかどうか
			if line =~ /@series\.settoall_linewidth_active="(.*?)"/ then
				case $1
				when "true" then
					@series.settoall_linewidth_active = true
				when "false" then
					@series.settoall_linewidth_active = false
				end
			end
		end
	end #}}}

	# 軸セット
	def set_axis(gp_cont,ins_axis,re_axis) #{{{
		# デフォルト値セット
		ins_axis.label           = ""
		ins_axis.label_offset    = 0
		ins_axis.label_fontsize  = "26"
		ins_axis.scale           = "lin"
		ins_axis.format_exp      = "auto"
		ins_axis.digits_adp      = 1
		ins_axis.format_fontsize = "26"
		ins_axis.min             = "*"
		ins_axis.max             = "*"
		ins_axis.tics_manual     = false
		ins_axis.tics_min        = ""
		ins_axis.tics_step       = ""
		ins_axis.tics_max        = ""
		ins_axis.mtics_manual    = false
		ins_axis.mtics_freq      = 5
		ins_axis.grid_show       = false
		ins_axis.mgrid_show      = false
		gp_cont.each do |line|
			re_label = /#{re_axis}l(?:a(?:b(?:el?)?)?)?/
			if line =~ /^\s*set?\s+#{re_label}\s+"(.*?)"\s+(.*)/ then
				label_title = $1
				label_opt = $2
				ins_axis.label = label_title.gsub(/\\n$/,"")
				if label_opt =~ /font\s+"(.*?)(?:,(\d+))?"/ then
					ins_axis.label_fontsize = $2.to_s
				end
				re_offset = /of(?:f(?:s(?:et?)?)?)?/
				if label_opt =~ /(?:^|\s)(?:#{re_offset}\s+)?(#{$re_float})\s*,\s*(#{$re_float})(\s|$)/ then
					case ins_axis
					when @xaxis then
						ins_axis.label_offset = $2.to_f*(-1.0)
					when @yaxis then
						ins_axis.label_offset = $1.to_f*(-1.0)
					when @y2axis then
						ins_axis.label_offset = $1.to_f
					end
				end
			end
			re_logscale = /log(?:s(?:c(?:a(?:le?)?)?)?)?/
			if line =~ /^\s*set?\s+#{re_logscale}\s+\w*#{re_axis}/ then
				ins_axis.scale = "log"
			end
			re_format = /fo(?:r(?:m(?:at?)?)?)?/
			if line =~ /^\s*set?\s+#{re_format}\s+#{re_axis}\s+"(.*?)"/ then
				spec = $1.scan(/\%[ \#\+\-0]*(\d*)(?:\.(\d))?([feEgGxXoOtTlLsScP])/)
				spec_flt = false
				spec_exp = false
				spec_expflt = false
				spec.each do |sp|
					if sp[2] == "f" then
						spec_flt = true
						ins_axis.digits_adp = sp[1].to_i
					elsif sp[2] == "T" || sp[2] == "L" then
						spec_exp = true
					elsif sp[2] == "t" then
						spec_expflt = true
						ins_axis.digits_adp = sp[1].to_i
					end
				end
				if spec_flt then
					ins_axis.format_exp = "float"
				elsif spec_exp && spec_expflt then
					ins_axis.format_exp = "fltexp"
				elsif spec_exp then
					ins_axis.format_exp = "exponent"
				else
					ins_axis.format_exp = "auto"
				end
			end
			re_tics = /#{re_axis}ti(?:cs?)?/
			if line =~ /^\s*set?\s+#{re_tics}\s+(.*)/ then
				tics_opt = $1
				if tics_opt =~ /font\s+"(.*?)(?:,(\d+))?"/ then
					ins_axis.format_fontsize = $2.to_s
				end
				if tics_opt =~ /(?:^|[^(?:scale)]\s+)(#{$re_float})\s*,\s*(#{$re_float})(?:\s*,\s*(#{$re_float}))?/ then
					ins_axis.tics_manual = true
					ins_axis.tics_min = $1.to_s if $1
					ins_axis.tics_step = $2.to_s if $2
					ins_axis.tics_max = $3.to_s if $3
				end
			end
			re_range = /#{re_axis}r(?:a(?:n(?:ge?)?)?)?/
			if line =~ /^\s*set?\s+#{re_range}\s+(.*)/ then
				$1 =~ /\[\s*(#{$re_float}|\*)?\s*\:\s*(#{$re_float}|\*)?\s*\]/
				ins_axis.min = $1.to_s if $1
				ins_axis.max = $2.to_s if $2
			end
			re_mtics = /m#{re_axis}t(?:i(?:cs?)?)?/
			if line =~ /^\s*set?\s+#{re_mtics}\s+(\d+)/ then
				ins_axis.mtics_manual = true
				ins_axis.mtics_freq = $1.to_i
			end
			re_grid = /g(?:r(?:id?)?)?/
			if line =~ /^\s*set?\s+#{re_grid}\s+(.*)/ then
				$1.scan(/(m?)#{re_axis}tics/).each do |gr|
					if gr[0]=="m" then
						ins_axis.mgrid_show = true
					else
						ins_axis.grid_show = true
					end
				end
			end
		end
	end #}}}

	# 凡例セット
	def set_legend(gp_cont) #{{{
		# デフォルト値セット
		@legend.visible = true
		@legend.position = "right top"
		@legend.align = "Right"
		@legend.reverse = false
		@legend.spacing = 1.0
		@legend.width = 0
		@legend.fontsize = "20"
		gp_cont.each do |line|
			re_key = /k(?:ey?)?/
			if line =~ /^\s*uns(?:et?)?\s+#{re_key}\s*$/ then
				@legend.visible = false
			end
			if line =~ /^\s*set?\s+#{re_key}\s+(.*)/ then
				@legend.visible = true
				legend_opt = $1
				# 位置
				legend_pos_h = ""
				legend_pos_v = ""
				## 水平位置
				re_right = /r(?:i(?:g(?:ht?)?)?)?/
				re_left = /l(?:e(?:ft?)?)?/
				re_rmargin = /rm(?:a(?:r(?:g(?:in?)?)?)?)?/
				if legend_opt =~ /(^|\s)#{re_right}(\s|$)/ then
					legend_pos_h = "right"
				elsif legend_opt =~ /(^|\s)#{re_left}(\s|$)/ then
					legend_pos_h = "left"
				elsif legend_opt =~ /(^|\s)#{re_rmargin}(\s|$)/ then
					legend_pos_h = "rmargin"
				end
				## 垂直位置
				re_top = /t(?:op?)?/
				re_bottom = /b(?:o(?:t(?:t(?:om?)?)?)?)?/
				re_below = /be(?:l(?:ow?)?)?/
				if legend_opt =~ /(^|\s)#{re_top}(\s|$)/ then
					legend_pos_v = "top"
				elsif legend_opt =~ /(^|\s)#{re_bottom}(\s|$)/ then
					legend_pos_v = "bottom"
				elsif legend_opt =~ /(^|\s)#{re_below}(\s|$)/ then
					legend_pos_v = "below"
				end
				## 位置指示
				legend_pos_h = "center" if legend_pos_h == ""
				legend_pos_v = "center" if legend_pos_v == ""
				legend_positon = legend_pos_h + " " + legend_pos_v
				if legend_positon != "center center" then
					@legend.position = legend_positon
				end
				## 揃え方向
				re_Right = /R(?:i(?:g(?:ht?)?)?)?/
				re_Left = /L(?:e(?:ft?)?)?/
				if legend_opt =~ /(^|\s)#{re_Right}(\s|$)/ then
					@legend.align = "Right"
				elsif legend_opt =~ /(^|\s)#{re_Left}(\s|$)/ then
					@legend.align = "Left"
				end
				# 記号説明反転
				re_reverse = /rev(?:e(?:r(?:se?)?)?)?/
				if legend_opt =~ /(^|\s)no#{re_reverse}(\s|$)/ then
					@legend.reverse = false
				elsif legend_opt =~ /(^|\s)#{re_reverse}(\s|$)/ then
					@legend.reverse = true
				end
				# 上下間隔
				re_spacing = /sp(?:a(?:c(?:i(?:ng?)?)?)?)?/
				if legend_opt =~ /(?:^|\s)#{re_spacing}\s+(#{$re_float})(\s|$)/ then
					@legend.spacing = $1.to_f
				end
				# 幅調整
				re_width = /w(?:i(?:d(?:th?)?)?)?/
				if legend_opt =~ /(?:^|\s)#{re_width}\s+(#{$re_float})(\s|$)/ then
					@legend.width = $1.to_f
				end
			end
			re_terminal = /te(?:r(?:m(?:i(?:n(?:al?)?)?)?)?)?/
			re_postscript = /pos(?:t(?:s(?:c(?:r(?:i(?:pt?)?)?)?)?)?)?/
			if line =~ /^\s*set?\s+#{re_terminal}\s+#{re_postscript}\s+(.*)/ then
				term_opt = $1
				if term_opt =~ /(fontfile\s+)?"(.*?)(?:,(\d+))?"(?:\s+(\d+))?/
					# 凡例フォントサイズ
					if !$1 && $2 then
						@legend.fontsize = $3 if $3
						@legend.fontsize = $4 if $4
					end
				end
			end
		end
	end #}}}

	# その他セット
	def set_etc(gp_cont) #{{{
		# デフォルト値セット
		@etc.tmargin = ""
		@etc.bmargin = ""
		@etc.lmargin = ""
		@etc.rmargin = ""
		@etc.aspect_x   = 10
		@etc.aspect_y   = 7
		aspect_hit = 0
		gp_cont.each do |line|
			re_margin = /([tblr])mar(?:g(?:in?)?)?/
			if line =~ /^\s*set?\s+#{re_margin}\s+(\d+)(\s|$)/ then
				case $1
				when "t" then
					@etc.tmargin = $2
				when "b" then
					@etc.bmargin = $2
				when "l" then
					@etc.lmargin = $2
				when "r" then
					@etc.rmargin = $2
				end
			end
			if line =~ /@etc\.aspect_x="?(#{$re_float})"?/ then
				@etc.aspect_x = $1.to_i
				aspect_hit += 1
			end
			if line =~ /@etc\.aspect_y="?(#{$re_float})"?/ then
				@etc.aspect_y = $1.to_i
				aspect_hit += 1
			end
			re_terminal = /te(?:r(?:m(?:i(?:n(?:al?)?)?)?)?)?/
			re_postscript = /pos(?:t(?:s(?:c(?:r(?:i(?:pt?)?)?)?)?)?)?/
			if aspect_hit < 2 && line =~ /^\s*set?\s+#{re_terminal}\s+#{re_postscript}\s+(.*)/ then
				term_opt = $1
				if term_opt =~ /(?:^|\s)size\s+(#{$re_float})[a-zA-Z]*\s*,\s*(#{$re_float})[a-zA-Z]*(\s|$)/ then
					@etc.aspect_x = ($1.to_f*2).to_i
					@etc.aspect_y = ($2.to_f*2).to_i
				end
			end
		end
	end #}}}

	# オプションセット
	def set_option(option_cont) #{{{
		# デフォルト値セット
		@option.set_defaults
		option_cont.each do |line|
			if line =~ /@option\.cmd_gnuplot="(.*?)"/ then
				@option.cmd_gnuplot = $1
			end
			if line =~ /@option\.cmd_epsview="(.*?)"/ then
				@option.cmd_epsview =  $1
			end
			if line =~ /@option\.cmd_pngconv="(.*?)"/ then
				@option.cmd_pngconv = $1
			end
			if line =~ /@option\.cmd_pngview="(.*?)"/ then
				@option.cmd_pngview  = $1
			end
			if line =~ /@option\.cmd_datafileview="(.*?)"/ then
				@option.cmd_datafileview  = $1
			end
			if line =~ /@option\.plot_datapattern="(.*?)"/ then
				@option.plot_datapattern  = $1
			end
			if line =~ /@option\.plot_resetrow="(.*?)"/ then
				#@option.plot_resetrow  = $1
				@option.plot_resetrow  = true if $1 == "true"
				@option.plot_resetrow  = false if $1 == "false"
			end
			if line =~ /@option\.x11_fontsize="(\d*?)"/ then
				@option.x11_fontsize  = $1
			end
			if line =~ /@option\.fontname="(.*?)"/ then
				@option.fontname  = $1
			end
		end
		# バージョンチェックする
		@option.gp_old_ver_check
	end #}}}

	# 初期化関数
	# インスタンス群をハッシュで与える。
	def initialize (hash_ins) #{{{
		# オプション
		@option = hash_ins["option"]
		# 全般
		@general = hash_ins["general"]
		#@general.set_defaults(@option)
		# 系列
		@series = hash_ins["series"]
		#@series.set_defaults
		# x軸
		@xaxis = hash_ins["xaxis"]
		#@xaxis.set_defaults
		# y軸
		@yaxis = hash_ins["yaxis"]
		#@yaxis.set_defaults
		# 第2y軸
		@y2axis = hash_ins["y2axis"]
		#@y2axis.set_defaults
		# 凡例
		@legend = hash_ins["legend"]
		#@legend.set_defaults
		# その他
		@etc = hash_ins["etc"]
		#@etc.set_defaults

		# ダイアログを作っておく
		title = "スクリプトファイル読込"
		@dialog = Gtk::FileChooserDialog.new(
			title,nil,Gtk::FileChooser::ACTION_OPEN,nil,
			[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
			[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])

		# カレントディレクトリ
		@current_folder = nil
	end #}}}
end #}}}

# メイン
class MainWindow < Gtk::Window #{{{
	################################
	# メニューバー
	################################

	# メニューバーを作る
	# メニューバーのインスタンスを返す
	def get_menubar #{{{
		# コールバック定義
		## オプション
		cb_option = Proc.new do
			@option.show
		end
		menu_items = [
			["/ファイル(_F)"],
			["/ファイル(F)/スクリプト読込(_L)",Gtk::ItemFactory::STOCK_ITEM,"<CTRL>L",Gtk::Stock::OPEN,Proc.new{@session.load}],
			["/ファイル(F)/終了(_Q)",Gtk::ItemFactory::STOCK_ITEM,"<CTRL>Q",Gtk::Stock::QUIT,Proc.new{Gtk.main_quit}],

			["/オプション(_O)",Gtk::ItemFactory::BRANCH],
			["/オプション(O)/設定...",Gtk::ItemFactory::STOCK_ITEM,nil,Gtk::Stock::PREFERENCES,cb_option],

			["/ヘルプ(_H)", Gtk::ItemFactory::LAST_BRANCH],
			["/ヘルプ(H)/About",Gtk::ItemFactory::STOCK_ITEM,nil,Gtk::Stock::ABOUT,Proc.new{@msgdialog.show_about()}],
		]
		accel_group = Gtk::AccelGroup.new
		item_factory = Gtk::ItemFactory.new(Gtk::ItemFactory::TYPE_MENU_BAR, "<main>", accel_group)

		item_factory.create_items(menu_items)
		self.add_accel_group(accel_group)
		item_factory.get_widget("<main>")
	end #}}}

	# 設定ファイルの共通部分
	def gp_str_common #{{{
		# エラーフラグ
		flag_error = false
		errstr = ""
		# データファイルが存在するかチェック
		unless File.exist?(@general.datafile) then
			flag_error = true
			errstr += "デフォルトデータファイルが存在しません。:\n\"#{@general.datafile}\"\n"
		end
		# スクリプト出力先ディレクトリの存在をチェック
		unless File.directory?(File.dirname(@general.gpfile)) then
			flag_error = true
			errstr += "スクリプト出力先のディレクトリが存在しません。:\n\"#{File.dirname(@general.gpfile)}\"\n"
		end
		# eps出力先ディレクトリの存在をチェック
		unless File.directory?(File.dirname(@general.epsfile)) then
			flag_error = true
			errstr += "eps出力先のディレクトリが存在しません。:\n\"#{File.dirname(@general.epsfile)}\"\n"
		end
		# png出力先ディレクトリの存在をチェック
		unless File.directory?(File.dirname(@general.pngfile)) then
			flag_error = true
			errstr += "png出力先のディレクトリが存在しません。:\n\"#{File.dirname(@general.pngfile)}\"\n"
		end
		if flag_error then
			@msgdialog.error_dialog(errstr)
			return nil
		end
		# 第2Y軸が使用されているかチェック
		y2axis_active =false
		@series.plot_series.each do |ps|
			y2axis_active = true if ps.y2axis
		end
		# 出力文字列生成開始
		outstr = ""
		s= <<-EOS
		# コメント開始文字
		set datafile commentschars "#{@general.commentschars}"

		EOS
		s += "# 区切り文字\n"
		case @general.separator
		when "whitespace"
		s += "set datafile separator whitespace\n"
		else
		s += "set datafile separator \"#{@general.separator}\"\n"
		end
		s += "\n"

		s+= <<-EOS
		# スタイルの設定
		# # 線の見た目設定(実線/点線タイプ、線幅、色)
		# # 使用可能な色の名前は"show palette color"とgnuplot上で打てば出る。
		# デフォルトは以下
		# linetype(線種):1(実線)
		# linewidth(線幅):3
		# pointtype(ポイントの種類):(順に)12,6,4,8,10,13,7,5,9,11,1
		# linecolor(色):(順に)red,blue,dark-green,dark-magenta,dark-cyan,coral,
		#               dark-pink,brown,dark-turquoise,orange-red,goldenrod
		EOS
		unless @option.flag_gp_old_ver then
			s += "set style increment user\n"
		end

		tmp_i = 1
		#pt_order = [12,6,4,8,10,13,7,5,9,11,1]
		@series.plot_series.each do |ps|
			s += "set style line #{tmp_i} linetype #{ps.linetype}"
			s += " linewidth #{ps.linewidth} pointtype #{ps.pointtype}"
			unless @option.flag_gp_old_ver then
				s += " linecolor rgb \"#{ps.linecolor}\""
			end
			s += "\n"
			tmp_i += 1
		end
		s += "\n"

		s+= <<-EOS
		# プロットポイントの大きさ
		set pointsize #{@series.pointsize}

		# 線形/対数軸
		unset logscale
		EOS
		s += "set logscale x\n" if @xaxis.scale == "log"
		s += "set logscale y\n" if @yaxis.scale == "log"
		s += "set logscale y2\n" if @y2axis.scale == "log"
		s += "\n"


		s += "# 軸のラベル\n"
		# 凡例がグラフ下でなければ改行を入れる(切れるの防止)
		if @legend.position  =~ /below/ && @legend.visible then
			xlabel = @xaxis.label
		else
			xlabel = @xaxis.label + "\\n"
		end
		# ラベル位置調整の符号処理
		xlabel_offset = -1.0*@xaxis.label_offset
		ylabel_offset = -1.0*@yaxis.label_offset
		y2label_offset = @y2axis.label_offset
		# キーワード"offset"をバージョンによって入れるかどうか
		if @option.flag_gp_old_ver then
			str_offset = ""
		else
			str_offset = "offset"
		end
		s+= <<-EOS
		set xlabel "#{xlabel}" #{str_offset} 0,#{xlabel_offset} font "#{@option.fontname},#{@xaxis.label_fontsize}"
		set ylabel "#{@yaxis.label}" #{str_offset} #{ylabel_offset},0 font "#{@option.fontname},#{@yaxis.label_fontsize}"
		EOS

		if y2axis_active then
		s+= <<-EOS
		set y2label "#{@y2axis.label}" #{str_offset} #{y2label_offset},0 font "#{@option.fontname},#{@y2axis.label_fontsize}"
		EOS
		end
		s += "\n"

		s += "# 数値表示形式\n"
		case @xaxis.format_exp
		when "auto"
			s += "set format x \"%g\"\n"
		when "float"
			s += "set format x \"%.#{@xaxis.digits_adp.to_s}f\"\n"
		when "exponent"
			s += "set format x \"10^{%T}\"\n"
		when "fltexp"
			s += "set format x \"%.#{@xaxis.digits_adp.to_s}t{/Symbol \\264}10^{%T}\"\n"
		end

		case @yaxis.format_exp
		when "auto"
			s += "set format y \"%g\"\n"
		when "float"
			s += "set format y \"%.#{@yaxis.digits_adp.to_s}f\"\n"
		when "exponent"
			s += "set format y \"10^{%T}\"\n"
		when "fltexp"
			s += "set format y \"%.#{@yaxis.digits_adp.to_s}t{/Symbol \\264}10^{%T}\"\n"
		end

		case @y2axis.format_exp
		when "auto"
			s += "set format y2 \"%g\"\n"
		when "float"
			s += "set format y2 \"%.#{@y2axis.digits_adp.to_s}f\"\n"
		when "exponent"
			s += "set format y2 \"10^{%T}\"\n"
		when "fltexp"
			s += "set format y2 \"%.#{@y2axis.digits_adp.to_s}t{/Symbol \\264}10^{%T}\"\n"
		end

		s+= <<-EOS

		# 軸の範囲
		EOS
		# 空白は"*"に置き換える
		axis_ranges = {
			"xmin"  => @xaxis.min,
			"xmax"  => @xaxis.max,
			"ymin"  => @yaxis.min,
			"ymax"  => @yaxis.max,
			"y2min" => @y2axis.min,
			"y2max" => @y2axis.max,
		}
		#p axis_ranges
		axis_ranges.dup.each do |key,val|
			if val == "" then
				axis_ranges[key] = "*"
			end
		end
		#p axis_ranges
		s+= <<-EOS
		set xrange [#{axis_ranges["xmin"]}:#{axis_ranges["xmax"]}]
		set yrange [#{axis_ranges["ymin"]}:#{axis_ranges["ymax"]}]
		set y2range [#{axis_ranges["y2min"]}:#{axis_ranges["y2max"]}]

		# 目盛
		set xtics font "#{@option.fontname},#{@xaxis.format_fontsize}"
		set ytics font "#{@option.fontname},#{@yaxis.format_fontsize}"
		EOS

		if y2axis_active then
			s+= <<-EOS
			set ytics nomirror
			set y2tics font "#{@option.fontname},#{@y2axis.format_fontsize}"
			EOS
		end

		if @xaxis.tics_manual then
			s += "set xtics #{@xaxis.tics_min},#{@xaxis.tics_step},#{@xaxis.tics_max}\n"
		else
			s += "set xtics autofreq\n"
		end

		if @yaxis.tics_manual then
			s += "set ytics #{@yaxis.tics_min},#{@yaxis.tics_step},#{@yaxis.tics_max}\n"
		else
			s += "set ytics autofreq\n"
		end

		if y2axis_active then
			if @y2axis.tics_manual then
				s += "set y2tics #{@y2axis.tics_min},#{@y2axis.tics_step},#{@y2axis.tics_max}\n"
			else
				s += "set y2tics autofreq\n"
			end
		end

		s += "set mxtics #{@xaxis.mtics_freq}\n" if @xaxis.mtics_manual
		s += "set mytics #{@yaxis.mtics_freq}\n" if @yaxis.mtics_manual
		s += "set my2tics #{@y2axis.mtics_freq}\n" if @y2axis.mtics_manual && y2axis_active

		s += "\n# グリッド\n"
		if @xaxis.grid_show
			s += "set grid xtics"
			s += " mxtics" if @xaxis.mgrid_show
			s += "\n"
		end
		if @yaxis.grid_show
			s += "set grid ytics"
			s += " mytics" if @yaxis.mgrid_show
			s += "\n"
		end
		if @y2axis.grid_show
			s += "set grid y2tics"
			s += " my2tics" if @y2axis.mgrid_show
			s += "\n"
		end
		s += "\n"

		s+= <<-EOS
		# 凡例
		set key noreverse
		set key #{@legend.position} #{@legend.align} #{"reverse" if @legend.reverse}
		set key spacing #{@legend.spacing}
		set key width #{@legend.width}
		EOS
		unless @legend.visible then
			s += "unset key\n"
		end
		#s += "set key box \n"
		s += "\n"

		s += "# 余白\n"
		s += "set tmargin #{@etc.tmargin}\n" if @etc.tmargin != ""
		s += "set bmargin #{@etc.bmargin}\n" if @etc.bmargin != ""
		s += "set lmargin #{@etc.lmargin}\n" if @etc.lmargin != ""
		s += "set rmargin #{@etc.rmargin}\n" if @etc.rmargin != ""
		s += "\n"

		s+= <<-EOS
		# グラフの縦横比
		# set size よりも set terminal の size オプションで制御したほうが
		# うまくいくので、gnuplot ver4.2以降では全体に描画する。
		EOS
		if @option.flag_gp_old_ver then
		s += "set size ratio #{@etc.aspect_y.to_f/@etc.aspect_x.to_f}\n"
		else
		s += "set size 1,1\n"
		end
		s += "\n"

		s += "# プロット命令\n"
		tmp_first = true
		tmp_i = 0
		@series.plot_series.each do |ps|
			if tmp_first then
				s += "plot \\\n"
				tmp_first = false
			else
				s += ",\\\n"
			end
			tmp_i += 1
			#s += "\"#{@general.datafile}\" using "
			s += "\"#{ps.datafile}\" using "
			x_expr_is_1 = false
			if ps.x_expr =~ /^\s*((#{$re_float})\s*\*\s*)?(x)(\s*\*\s*(#{$re_float}))?\s*$/
				x_expr_is_1 = ($2.to_f == 1.0 || $2 == nil) && ($5.to_f == 1.0 || $5 == nil)
			end
			#p x_expr_is_1
			if ps.x_expr == "" || x_expr_is_1
				s += "#{ps.x_row}"
			else
				x_expr = ps.x_expr.gsub(/x|X/,"$#{ps.x_row}").gsub(/y|Y/,"$#{ps.y_row}")
				#p x_expr
				s += "(#{x_expr})"
			end
			s += ":"
			y_expr_is_1 = false
			if ps.y_expr =~ /^\s*((#{$re_float})\s*\*\s*)?(y)(\s*\*\s*(#{$re_float}))?\s*$/
				y_expr_is_1 = ($2.to_f == 1.0 || $2 == nil) && ($5.to_f == 1.0 || $5 == nil)
			end
			#p y_expr_is_1
			if ps.y_expr == "" || y_expr_is_1
				s += "#{ps.y_row} "
			else
				y_expr = ps.y_expr.gsub(/y|Y/,"$#{ps.y_row}").gsub(/x|X/,"$#{ps.x_row}")
				#p y_expr
				s += "(#{y_expr})"
			end
			s += " axis x1y2" if ps.y2axis
			s += " with #{ps.linestyle}"
			if @option.flag_gp_old_ver then
				s += " linestyle #{tmp_i}"
			end
			s += " title \"#{ps.title}\""
		end
		s += "\n\n"

		s.each do |l|
			outstr << l.strip + "\n"
		end

		return outstr
	end #}}}

	# eps出力部がついた設定ファイルの中身
	def gp_str_witheps(prev=false) #{{{
		if prev then
			target_epsfile = @prev_epsfile
		else
			target_epsfile = @general.epsfile
		end

		s = gp_str_common()
		return nil unless s

		termsize_x_def = 5
		termsize_y_def = 3.5
		if @legend.position =~ /rmargin/ then
			ps_title_lengths = []
			@series.plot_series.each do |ps|
				ps_title_lengths << ps.title.length
			end
			# グラフの比率を変えないための幅調節パラメータ
			legend_title_length = (ps_title_lengths.max + @legend.width + 4) * @legend.fontsize.to_f / (72*2) * 0.62
			#p legend_title_length
			termsize_x_mod = legend_title_length
		else
			termsize_x_mod = 0.0
		end
		termsize_y_mod = 0.0
		aspect_ratio = @etc.aspect_y.to_f/@etc.aspect_x.to_f
		if aspect_ratio >= 0.7 then
			termsize_x = "#{termsize_x_def + termsize_x_mod}inch"
			termsize_y = (termsize_x_def*aspect_ratio + termsize_y_mod).to_s + "inch"
		else
			termsize_x = (termsize_y_def/aspect_ratio + termsize_x_mod).to_s + "inch"
			termsize_y = "#{termsize_y_def + termsize_y_mod}inch"
		end

		outstr = <<-EOS

		EOS
		outstr += "# eps出力\n"
		outstr += "set terminal postscript eps enhanced "
		outstr += "color \"#{@option.fontname}\" #{@legend.fontsize} "
		unless @option.flag_gp_old_ver then
			outstr += "size #{termsize_x},#{termsize_y}"
		end
		outstr += "\n"
		outstr += <<-EOS
		set output "#{target_epsfile}"

		EOS

		outstr += s
		return outstr
	end #}}}

	# スクリプト出力
	def gp_conf_out(filename ,silent = false) #{{{
		gnuplot_fullpath = `which #{@option.cmd_gnuplot.split(/\s+/)[0]}`.strip
		s = <<-EOS
		#!#{gnuplot_fullpath}
		# This file is made by gpgui.
		# Tool options are written in lines started with "#%".
		#% @general.datafile="#{@general.datafile}"
		#% @general.pngfile="#{@general.pngfile}"
		#% @series.x_expr_def="#{@series.x_expr_def}"
		#% @series.y_expr_def="#{@series.y_expr_def}"
		#% @series.linestyle_def="#{@series.linestyle_def}"
		#% @series.linewidth_def="#{@series.linewidth_def}"
		#% @series.settoall_x_expr_active="#{@series.settoall_x_expr_active}"
		#% @series.settoall_y_expr_active="#{@series.settoall_y_expr_active}"
		#% @series.settoall_linestyle_active="#{@series.settoall_linestyle_active}"
		#% @series.settoall_linewidth_active="#{@series.settoall_linewidth_active}"
		#% @etc.aspect_x="#{@etc.aspect_x}"
		#% @etc.aspect_y="#{@etc.aspect_y}"
		EOS
		w = gp_str_witheps
		return nil unless w
		s += w

		f = open(filename,"w")

		s.each do |l|
			f.puts l.strip
		end
		f.close

		if File.exist?(filename) then
			@msgdialog.info_dialog("\"#{filename}\"に書き込みました。") unless silent
			File.chmod(0755,filename)
		else
			@msgdialog.error_dialog("エラー : 設定ファイルの作成に失敗しました。")
		end

		return true
	end #}}}

	# プレビュー(X11)
	def gp_prev #{{{
		outstr = <<-EOS
		# This file is made by gpgui.

		# プレビューのためX11端末に出力
		set terminal x11 enhanced font "#{@option.fontname},#{@option.x11_fontsize}"
		EOS
		s = gp_str_common
		return nil unless s
		outstr += s

		# スレッド版
		# スレッドを生成してプレビュー維持のためsleepさせる。
		Thread.new(@option) do |op|
			open("|"+op.cmd_gnuplot,"w") do |gp|
				gp.puts outstr
				sleep()
			end
		end
	end #}}}

	# eps出力
	def gp_epsout(silent = false, prev=false) #{{{
		if prev then
			target_epsfile = @prev_epsfile
		else
			target_epsfile = @general.epsfile
		end
		# 開始前に消す
		#if File.exist?(target_epsfile) then
		#	File.delete(target_epsfile)
		#end
		# スレッド版
		outstr = gp_str_witheps(prev)
		return nil unless outstr
		# スレッドを生成してeps作成
		th = Thread.new(@option) do |op|
			open("|"+op.cmd_gnuplot,"w") do |gp|
				gp.puts outstr
			end
		end
		# スレッド終了を待つ
		th.join
		if File.exist?(target_epsfile) && !File.zero?(target_epsfile) then
			unless silent then
				`which #{@option.cmd_epsview.split(/\s+/)[0]} >& /dev/null` # (systemよりも``のほうが高速)
				unless $?.exitstatus == 0 then
					@msgdialog.info_dialog("#{target_epsfile}を作成しました。\n\nepsビューアコマンド\"#{@option.cmd_epsview}\"が見つからないため、\n表示をスキップします。")
				else
					pid = fork{
						exec(@option.cmd_epsview+' "'+target_epsfile+'"')
					}
					Process.detach(pid)
					#$child_pids << pid
				end
			end
		else
			@msgdialog.error_dialog("エラー : epsファイルの作成に失敗しました。")
			return nil
		end

		return target_epsfile

	end #}}}

	# png出力
	def gp_pngout(button = nil) #{{{
		proc_ok = Proc.new do
			png_dirname = File.dirname(@general.pngfile)
			png_basename = File.basename(@general.pngfile,File.extname(@general.pngfile))
			@general.pngfile = File.join(png_dirname,png_basename) + ".png"
			png_conv_view(button)
		end
		proc_cancel = Proc.new do
		end
		re_ext = /^\.(png)$/
		unless File.extname(@general.pngfile) =~ re_ext then
			@msgdialog.confirm_dialog("拡張子が\".png\"ではありません。\n修正しますか?",proc_ok,proc_cancel)
		else
			png_conv_view(button)
		end
	end #}}}

	# png変換->表示
	def png_conv_view(button = nil) #{{{
		return nil unless gp_epsout(true)
		# 開始前に消す
		#if File.exist?(@general.pngfile) then
		#	File.delete(@general.pngfile)
		#end
		if File.exist?(@general.epsfile) && !File.zero?(@general.epsfile) then
			tcmd_pngconv = @option.cmd_pngconv.gsub("%e",'"'+@general.epsfile+'"')
			tcmd_pngconv.gsub!("%p",'"'+@general.pngfile+'"')
			`which #{@option.cmd_pngconv.split(/\s+/)[0]} >& /dev/null` # (systemよりも``のほうが高速)
			unless $?.exitstatus == 0 then
				@msgdialog.error_dialog("eps->png変換コマンド\"#{basecmd_pngconv}\"が見つかりません。")
				return nil
			end
			pid = fork{
				exec(tcmd_pngconv)
			}
			th = Process.detach(pid)
			# 変換終了まで待って表示
			Thread.new do
				button.sensitive = false if button
				@progmsg.reset
				tmp_count = 0
				loop do
					#p th.status
					break unless th.alive?
					sleep(0.1)
					@progmsg.pulse if tmp_count%4 == 0
					tmp_count += 1
				end
				if File.exist?(@general.pngfile) && !File.zero?(@general.pngfile) then
					# ビューアコマンドがあるかどうか確かめる
					`which #{@option.cmd_pngview.split(/\s+/)[0]} >& /dev/null` # (systemよりも``のほうが高速)
					unless $?.exitstatus == 0 then
						@msgdialog.info_dialog("#{@general.pngfile}を作成しました。\n\npngビューアコマンド\"#{@option.cmd_pngview}\"が見つからないため、\n表示をスキップします。")
						#return nil
					else
						pid = fork{
							exec(@option.cmd_pngview+' "'+@general.pngfile+'"')
						}
						Process.detach(pid)
						#$child_pids << pid
					end
				else
					@msgdialog.error_dialog("エラー : pngファイルの作成に失敗しました。")
				end
				@progmsg.done
				button.sensitive = true if button
			end
		else
			@msgdialog.error_dialog("エラー : epsファイルがありません。")
			return nil
		end

		return @general.pngfile
	end #}}}

	#####################
	# 初期化関数
	#####################
	def initialize #{{{
		##############################
		# インスタンス変数定義
		##############################
		#{{{
		# インスタンス格納ハッシュ
		hash_ins = Hash::new
		# オプション
		@option = OptionDialog.new
		hash_ins["option"] = @option
		# 全般
		@general = PageGeneral.new(@option)
		@option.ins_general = @general
		hash_ins["general"] = @general
		# 系列
		@series = PageSeries.new(@option)
		hash_ins["series"] = @series
		# x軸
		@xaxis = PageAxis.new
		hash_ins["xaxis"] = @xaxis
		# y軸
		@yaxis = PageAxis.new
		hash_ins["yaxis"] = @yaxis
		# 第2y軸
		@y2axis = PageAxis.new
		hash_ins["y2axis"] = @y2axis
		# 凡例
		@legend = PageLegend.new
		hash_ins["legend"] = @legend
		# その他
		@etc = PageEtc.new
		hash_ins["etc"] = @etc
		# プログレスメッセージ
		@progmsg = ProgressMessage.new
		# メッセージダイアログ
		@msgdialog = MessageDialog.new

		# セッション
		@session = Session.new(hash_ins)
		#}}}

		# オプションを読み込む
		@session.option_import

		# プレビュー用のテンポラリファイル名
		@prev_epsfile = "/tmp/gpgui_prev-#{ENV['USER']}.eps"

		##############################
		# ウィンドウレイアウト
		##############################
		#{{{
		super()
		vbox_main = Gtk::VBox.new(false,0)
		self.add(vbox_main)
		# メニューバーを生成
		menubar = get_menubar
		vbox_main.pack_start(menubar,false,true,0)

		# ノートブックとタブの設定
		notebook = Gtk::Notebook.new
		notebook.tab_pos = Gtk::POS_TOP
		vbox_main.pack_start(notebook,true,true,5)

		# 「全般」設定ページ
		notebook.append_page(@general.get_page,Gtk::Label.new("全般"))

		# 「系列」設定ページ
		notebook.append_page(@series.get_page,Gtk::Label.new("系列"))

		# 「x軸」設定ページ
		notebook.append_page(@xaxis.get_page,Gtk::Label.new("X軸"))
		@xaxis.label = "xlabel"

		# 「y軸」設定ページ
		notebook.append_page(@yaxis.get_page,Gtk::Label.new("Y軸"))
		@yaxis.label = "ylabel"

		# 「第2y軸」設定ページ
		notebook.append_page(@y2axis.get_page,Gtk::Label.new("第2Y軸"))
		@y2axis.label = "y2label"

		# 「凡例」設定ページ
		notebook.append_page(@legend.get_page,Gtk::Label.new("凡例"))

		# 「スタイル」設定ページ
		#notebook.append_page(@style.get_page,Gtk::Label.new("スタイル"))

		# 「その他」設定ページ
		notebook.append_page(@etc.get_page,Gtk::Label.new("その他"))

		# セパレータ
		#separator = Gtk::HSeparator.new
		#vbox_main.pack_start(separator,false,false,5)

		# 下部ボックス
		hbox_under = Gtk::HBox.new(false,0)
		vbox_main.pack_start(hbox_under,false,false,0)

		# 処理ボタン
		bbox = Gtk::HButtonBox.new
		bbox.border_width = 5
		bbox.layout_style = Gtk::ButtonBox::END
		bbox.spacing = 10
		hbox_under.pack_end(bbox,false,false,0)

		button_prev    = Gtk::Button.new("プレビュー")
		button_conf    = Gtk::Button.new("スクリプト出力")
		button_epsprev = Gtk::Button.new("epsプレビュー")
		button_eps     = Gtk::Button.new("eps出力")
		button_png     = Gtk::Button.new("png出力")
		# 現在無効(非表示)
		#bbox.add(button_prev)
		bbox.add(button_conf)
		bbox.add(button_epsprev)
		bbox.add(button_eps)
		bbox.add(button_png)

		# プログレスメッセージ
		hbox_under.pack_start(@progmsg,false,false,5)

		# 処理ボタンに処理メソッドを割り当て
		button_prev.signal_connect("clicked") do
			gp_prev()
		end
		button_conf.signal_connect("clicked") do
			gp_conf_out(@general.gpfile)
		end
		button_epsprev.signal_connect("clicked") do
			gp_epsout(false,true)
		end
		button_eps.signal_connect("clicked") do
			gp_epsout()
		end
		button_png.signal_connect("clicked") do
			gp_pngout(button_png)
		end
		#}}}
	end #}}}
end #}}}

window = MainWindow.new
window.title = "gpgui"
window.set_default_size(300,300)
window.signal_connect("destroy") do
	Gtk.main_quit
	# 子プロセスを切る
	#p $child_pids
	#$child_pids.each do |pid|
	#	Process.kill(:KILL,pid)
	#end
end
window.show_all
Gtk.main


