あけおめことよろ、遅い?
さて今年もプログラミングてゆーかソフトウエア作るぞと。
ところで前回の IronPython でタスクトレイは結構人が来ている、実際自分で利用しているし。
やっぱり Windows でのネタでないとアクセスが稼げないなと実感しまくる。
そういえば以前こんなのを書いたけど
ぱぇぽぃ2 ? Blog Archive ? IronPython は親クラスの __init__() がいらない
IronPython での open は StreamReader と同じなのかな?
なんて思ったので実験コードを書いて試してみた。
結果だけではつまらないのでシンプルなテキストエディタを作ってみる。
海外から結構見に来るので全部英語で書くけど日本語向けコードだと解るように。
ちなみに Google 翻訳を駆使しているだけなので翻訳が合っているかどうか解らない。
# -*- coding: UTF-8 -*-
"""
This Code is Suitable for Japanese
XAML [xml:lang] Own Rewrite
Read and Write encoding is UTF-8 Non BOM Text
"""
import clr
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")
# Open,SaveFileDialog
clr.AddReferenceByPartialName("System.Windows.Forms")
from System import *
from System.IO import *
from System.Windows import *
from System.Windows.Controls import *
from System.Windows.Input import *
from System.Windows.Controls.Primitives import *
from System.Windows.Markup import XamlReader
# avoid namespace conflict
from System.Windows.Forms import OpenFileDialog, SaveFileDialog, DialogResult
menu_str = """<Menu
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="ja-JP">
<MenuItem Header="_File">
<MenuItem Header="_Open" InputGestureText="Ctrl+O" Name="menu_open" />
<MenuItem Header="_Save" InputGestureText="Ctrl+S" Name="menu_save" />
<MenuItem Header="Save _As" Name="menu_save_as" />
<Separator/>
<MenuItem Header="_Quit" InputGestureText="Ctrl+Q" Name="menu_close" />
</MenuItem>
</Menu>"""
class WPF_TextEditor(Window):
"""
Simple TextEditor
"""
def __init__(self):
"""
Initialization
"""
self.openfile = ""
# Menu
menu = XamlReader.Parse(menu_str)
menu.FindName("menu_open").Click += self.on_open
menu.FindName("menu_save").Click += self.on_save
menu.FindName("menu_save_as").Click += self.on_save_as
menu.FindName("menu_close").Click += self.on_close
DockPanel.SetDock(menu, Dock.Top)
# TextBox
self.textbox = TextBox()
self.textbox.TextWrapping = TextWrapping.NoWrap
self.textbox.AcceptsReturn = True
self.textbox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto
self.textbox.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto
# StatusBar
statusbar = StatusBar()
DockPanel.SetDock(statusbar, Dock.Bottom)
self.statusbar_item = StatusBarItem()
self.statusbar_item.Content = "no open"
statusbar.Items.Add(self.statusbar_item)
# DockPanel
dpanel = DockPanel()
dpanel.Children.Add(menu)
dpanel.Children.Add(statusbar)
dpanel.Children.Add(self.textbox)
# self
self.Content = dpanel
self.Title = "WPF_TextEditor"
# event
self.KeyDown += self.on_keydown
# Drag and drop
self.AllowDrop = True
self.PreviewDragOver += self.on_predrop
self.Drop += self.on_drop
def on_open(self, sender, e):
"""
namespace Microsoft Dialog is Old
"""
dlg = OpenFileDialog()
dlg.Title = "OpenFile"
if dlg.ShowDialog() == DialogResult.OK:
self.read_file(dlg.FileName)
def on_save(self, sender, e):
"""
is Open ?
"""
if self.openfile == "":
self.on_save_as(sender, e)
else:
self.save_file(self.openfile)
def on_save_as(self, sender, e):
"""
namespace Microsoft Dialog is Old
"""
dlg = SaveFileDialog()
dlg.Title = "SaveFile"
if dlg.ShowDialog() == DialogResult.OK:
self.save_file(dlg.FileName)
def on_close(self, sender, e):
"""
Bye
"""
self.Close()
def on_keydown(self, sender, e):
"""
InputGestureText is Show only
e is System.Windows.Input.KeyEventArgs
"""
if Keyboard.Modifiers == ModifierKeys.Control:
if e.Key == Key.O:
self.on_open(self, e)
elif e.Key == Key.S:
self.on_save(self, e)
elif e.Key == Key.Q:
self.on_close(self, e)
def on_predrop(self, sender, e):
"""
PreviewDragOver Event
"""
e.Handled = e.Data.GetData(DataFormats.FileDrop) != None
def on_drop(self, sender, e):
"""
File Dropped
"""
filenames = e.Data.GetData(DataFormats.FileDrop)
filename = filenames[0].ToString()
if filename != None and filename.Length != 0:
self.read_file(filename)
def read_file(self, filename):
"""
f = open(filename)
try:
s = f.read()
self.textbox.Text = unicode(s, "utf8")
except Exception, ex:
MessageBox.Show(ex.Message)
finally:
f.close()
"""
sw = StreamReader(filename)
try:
self.textbox.Text = sw.ReadToEnd()
self.statusbar_item.Content = Path.GetFileName(filename)
self.openfile = filename
except Exception, ex:
MessageBox.Show(ex.Message)
finally:
sw.Close()
def save_file(self, filename):
"""
f = open(filename, "w")
try:
f.write(self.textbox.Text.encode("utf8"))
except Exception, ex:
MessageBox.Show(ex.Message)
finally:
f.close()
"""
sw = StreamWriter(filename)
try:
buf = self.textbox.Text
sw.Write(buf)
self.statusbar_item.Content = Path.GetFileName(filename)
self.openfile = filename
except Exception, ex:
MessageBox.Show(ex.Message)
finally:
sw.Close()
if __name__ == "__main__":
Application().Run(WPF_TextEditor())
StreamReader で encode 無指定だと BOM 無し UTF-8 で読み書きになる。
けど open() では変換が必要なんだね、標準 Python に合わせたのだろうけど。
面倒くさいや、StreamReader を使ったほうが何かと便利そうだ。
メニューだけ XAML な所とか細かい所はこの Blog 過去ログを見て書いた。
結構色々やっていたんだな我ながら、まとめを兼ねて書いたようなものだ。
気が付いたけどこれだけで Ctrl+Z でのやり直しやテキストの D&D 編集ができる。
GtkSourceView ほど高機能ではないけど以外に使えるんでないかい TextBox って。