Top / Programming / Ruby / Ruby GUIライブラリ / FXRuby / FXRubyでメモ帳作成(5)開いて保存できるだけのメモ帳

FXRubyでメモ帳作成(5)

FXRubyでメモ帳を作成します。

開いて保存できるだけのメモ帳

複数行テキストコントロールを追加する

複数行テキストコントロール(複数行テキストコントロール)をフォームに追加します。

@textarea = FXText.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)

LAYOUT_FILL_X)は左右に、LAYOUT_FILL_Yは上下にコントロールを広げます。

[新規]メニュー

編集中のファイル名を@filenameに設定することにします。

class MemoWindow < FXMainWindow
  def initialize(app)
    super(app, "memo", nil, nil, DECOR_ALL, 0, 0, 400, 300)
    @filename = '' #編集中のファイル名

    新規メニューでは、複数行テキストコントロールの文字を空にし、編集中のファイル名を初期化します。
    FXMenuCommand.new(filemenu, "新規(&N)\tCtl-N").connect(SEL_COMMAND) {
      @textarea.setText("")
      @filename = ''
    }

[開く]メニュー

ファイルを開くダイアログは、FXFileDialogを使用します。

FXMenuCommand.new(filemenu, "開く(&O)\tCtl-O").connect(SEL_COMMAND) {
  openDialog = FXFileDialog.new(self, "開く")
  openDialog.selectMode = SELECTFILE_EXISTING
  openDialog.patternList = ["テキスト文書 (*.txt)", "全てのファイル (*.*)"]
  if openDialog.execute != 0
    loadFile(openDialog.filename)
  end
}

[名前を付けて保存]メニュー

[名前を付けて保存]の処理は、[上書き保存]メニューからも使用するので、onSaveAsメソッドを呼ぶことにします。

FXMenuCommand.new(filemenu, "名前を付けて保存(&A)").connect(SEL_COMMAND, method(:onSaveAs))

名前を付けて保存ダイアログは、FXFileDialogを使用します。

saveDialog = FXFileDialog.new(self, "名前を付けて保存")

選択されたファイルと同名のファイルがすでに存在するときは、FXMessageBox.questionを使用し、上書きの確認を行います。

if MBOX_CLICKED_NO == FXMessageBox.question(self, MBOX_YES_NO,
  "名前を付けて保存", mes)
  return 1
end

onSaveAsメソッドは次のようになります。

# 名前を付けて保存
def onSaveAs(sender, sel, ptr)
  saveDialog = FXFileDialog.new(self, "名前を付けて保存")
  if saveDialog.execute != 0
    if File.exists? saveDialog.filename
      mes = "#{saveDialog.filename}はすでに存在します。\n上書きしますか?"
      if MBOX_CLICKED_NO == FXMessageBox.question(self, MBOX_YES_NO,
        "名前を付けて保存", mes)
        return 1
      end
    end
    saveFile(saveDialog.filename)
  end
end

[上書き保存]メニュー

処理中のファイル名が設定されていれば、そのファイル名で保存します。 設定されていなければ、[名前を付けて保存]処理を行います。

FXMenuCommand.new(filemenu, "上書き保存(&S)\tCtl-S").connect(SEL_COMMAND) {|sender, sel, ptr|
  if @filename == ''
    onSaveAs(sender, sel, ptr)
  else
    saveFile(@filename)
  end
}

ソースコード

ここまでのソースコードです。

#!ruby -Ks

require 'fox'
include Fox

class MemoWindow < FXMainWindow
  def initialize(app)
    super(app, "memo", nil, nil, DECOR_ALL, 0, 0, 400, 300)
    @filename = '' #編集中のファイル名
    menubar = FXMenubar.new(self)

    filemenu = FXMenuPane.new(self)
    FXMenuTitle.new(menubar, "ファイル(&F)", nil, filemenu)
    FXMenuCommand.new(filemenu, "新規(&N)\tCtl-N").connect(SEL_COMMAND) {
      @textarea.setText("")
      @filename = ''
    }
    FXMenuCommand.new(filemenu, "開く(&O)\tCtl-O").connect(SEL_COMMAND) {
      openDialog = FXFileDialog.new(self, "開く")
      openDialog.selectMode = SELECTFILE_EXISTING
      openDialog.patternList = ["テキスト文書 (*.txt)", "全てのファイル (*.*)"]
      if openDialog.execute != 0
        loadFile(openDialog.filename)
      end
    }
    FXMenuCommand.new(filemenu, "上書き保存(&S)\tCtl-S").connect(SEL_COMMAND) {|sender, sel, ptr|
      if @filename == ''
        onSaveAs(sender, sel, ptr)
      else
        saveFile(@filename)
      end
    }
    FXMenuCommand.new(filemenu, "名前を付けて保存(&A)").connect(SEL_COMMAND, method(:onSaveAs))
    FXMenuSeparator.new(filemenu)
    FXMenuCommand.new(filemenu, "終了(&X)\tCtl-X", nil, getApp(), FXApp::ID_QUIT)

    editmenu = FXMenuPane.new(self)
    FXMenuTitle.new(menubar, "編集(&E)", nil, editmenu)
    FXMenuCommand.new(editmenu, "元に戻す(&U)\tCtl-Z").connect(SEL_COMMAND) {
      puts "元に戻す"
    }
    FXMenuSeparator.new(editmenu)
    FXMenuCommand.new(editmenu, "やり直し(&R)\tCtl-Y").connect(SEL_COMMAND) {
      puts "やり直し"
    }
    FXMenuCommand.new(editmenu, "切り取り(&T)\tCtl-X").connect(SEL_COMMAND) {
      puts "切り取り"
    }
    FXMenuCommand.new(editmenu, "コピー(&C)\tCtl-C").connect(SEL_COMMAND) {
      puts "コピー"
    }
    FXMenuCommand.new(editmenu, "貼り付け(&P)\tCtl-V").connect(SEL_COMMAND) {
      puts "貼り付け"
    }
    FXMenuCommand.new(editmenu, "削除(&L)").connect(SEL_COMMAND) {
      puts "削除"
    }
    FXMenuCommand.new(editmenu, "すべて選択(&A)\tCtl-A").connect(SEL_COMMAND) {
      puts "全て選択"
    }

    helpmenu = FXMenuPane.new(self)
    FXMenuCommand.new(helpmenu, "Memoについて(&A)").connect(SEL_COMMAND) {
      FXMessageBox.information(self, MBOX_OK, "memoについて",
        "簡単なテキストエディター")
    }
    FXMenuTitle.new(menubar, "&Help", nil, helpmenu, LAYOUT_RIGHT)

    @textarea = FXText.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
  end

  def create
    super
    show(PLACEMENT_SCREEN)
  end

  # 名前を付けて保存
  def onSaveAs(sender, sel, ptr)
    saveDialog = FXFileDialog.new(self, "名前を付けて保存")
    if saveDialog.execute != 0
      if File.exists? saveDialog.filename
        mes = "#{saveDialog.filename}はすでに存在します。\n上書きしますか?"
        if MBOX_CLICKED_NO == FXMessageBox.question(self, MBOX_YES_NO,
          "名前を付けて保存", mes)
          return 1
        end
      end
      saveFile(saveDialog.filename)
    end
  end

  def loadFile(filename)
    getApp().beginWaitCursor do
      text = File.open(filename, "r").read
      @textarea.setText(text)
      @filename = filename
    end
  end

  def saveFile(filename)
    getApp().beginWaitCursor do
      File.open(filename, "w") do |file|
        file.print @textarea.getText
      end
      @filename = filename
    end
  end
end

application = FXApp.new("memo", "yamamoto@gesource.jp")
MemoWindow.new(application)
application.create
application.run

memo画面キャプチャ memo画面キャプチャ

マルチバイト文字のところにキャレットを移動すると、文字化けが発生した。

更新履歴