-#!/usr/bin/env python\r
+#!/usr/bin/env python\r
# -*- coding: utf-8 -*-\r
\r
#Pydun.py - mapping tool\r
#copyright (c) 2013 WATAHIKI Hiroyuki\r
-#url: http://sourceforge.jp/projects/pydun/\r
+#url: http://osdn.jp/projects/pydun/\r
#email: hrwatahiki at gmail.com\r
+#twitter: @hrwatahiki\r
+#blog: http://hrwatahiki.blogspot.jp/\r
\r
\r
import sys\r
import os.path\r
-import codecs\r
import locale\r
+import urllib.request, urllib.parse, urllib.error\r
+import xml.etree.ElementTree\r
import webbrowser\r
from PySide import QtCore, QtGui\r
import yaml\r
_mapimages = None\r
_undomanager = None\r
\r
-projecturl = "http://sourceforge.jp/projects/pydun/"\r
-projectversion = "1.0.3"\r
+projecturl = "http://osdn.jp/projects/pydun/"\r
+projectrssurl = "http://osdn.jp/projects/pydun/releases/rss"\r
+projectversion = "1.1.0"\r
\r
\r
class MainWindow(QtGui.QMainWindow):\r
global _mapengine\r
global _mapimages\r
global _undomanager\r
+ global config\r
super(MainWindow, self).__init__(parent)\r
\r
_undomanager = UndoManager()\r
- _mapimages = MapImages()\r
+ _mapimages = MapImages(config.get("showWallMenuString", False))\r
self.setmenu()\r
_undomanager.changed.connect(self.updateundostate)\r
\r
self.new()\r
if len(sys.argv) >= 2:\r
- self.open(unicode(sys.argv[1], locale.getpreferredencoding()))\r
+ self.open(sys.argv[1])\r
\r
self.mainframe = MainFrame(self)\r
self.setCentralWidget(self.mainframe)\r
\r
self.statusbar = QtGui.QStatusBar(self)\r
- self.statusbar.showMessage(u"")\r
+ self.statusbar.showMessage("")\r
self.setStatusBar(self.statusbar)\r
if "windowSize" in config:\r
self.resize(\r
config["windowSize"]["height"]))\r
\r
def setmenu(self):\r
+ global config\r
#File menu\r
- filemenu = self.menuBar().addMenu(u"ファイル(&F)")\r
+ filemenu = self.menuBar().addMenu("ファイル(&F)")\r
\r
- newact = QtGui.QAction(u"新規(&N)", self)\r
+ newact = QtGui.QAction("新規(&N)", self)\r
newact.triggered.connect(self.new_triggered)\r
newact.setShortcut(QtGui.QKeySequence.New)\r
filemenu.addAction(newact)\r
\r
- openact = QtGui.QAction(u"開く(&O)...", self)\r
+ openact = QtGui.QAction("開く(&O)...", self)\r
openact.triggered.connect(self.open_triggered)\r
openact.setShortcut(QtGui.QKeySequence.Open)\r
filemenu.addAction(openact)\r
\r
- saveact = QtGui.QAction(u"上書き保存(&S)", self)\r
+ saveact = QtGui.QAction("上書き保存(&S)", self)\r
saveact.triggered.connect(self.save_triggered)\r
saveact.setShortcut(QtGui.QKeySequence.Save)\r
filemenu.addAction(saveact)\r
\r
- saveasact = QtGui.QAction(u"名前をつけて保存(&A)...", self)\r
+ saveasact = QtGui.QAction("名前をつけて保存(&A)...", self)\r
saveasact.triggered.connect(self.saveas_triggered)\r
saveasact.setShortcut(QtGui.QKeySequence.SaveAs)\r
filemenu.addAction(saveasact)\r
\r
- exitact = QtGui.QAction(u"終了(&E)", self)\r
+ exitact = QtGui.QAction("終了(&E)", self)\r
exitact.triggered.connect(self.exit_triggered)\r
exitact.setShortcut(QtGui.QKeySequence.Quit)\r
filemenu.addAction(exitact)\r
\r
#Edit menu\r
- editmenu = self.menuBar().addMenu(u"編集(&E)")\r
- self.undoact = QtGui.QAction(u"元に戻す(&U)", self)\r
+ editmenu = self.menuBar().addMenu("編集(&E)")\r
+ self.undoact = QtGui.QAction("元に戻す(&U)", self)\r
self.undoact.triggered.connect(self.undo_triggered)\r
self.undoact.setShortcut(QtGui.QKeySequence.Undo)\r
editmenu.addAction(self.undoact)\r
- self.redoact = QtGui.QAction(u"やり直し(&R)", self)\r
+ self.redoact = QtGui.QAction("やり直し(&R)", self)\r
self.redoact.triggered.connect(self.redo_triggered)\r
self.redoact.setShortcut(QtGui.QKeySequence.Redo)\r
editmenu.addAction(self.redoact)\r
editmenu.addSeparator()\r
- setmapsizeact = QtGui.QAction(u"マップのサイズ(&S)", self)\r
+ setmapsizeact = QtGui.QAction("マップのサイズ(&S)", self)\r
setmapsizeact.triggered.connect(self.setmapsize_triggered)\r
editmenu.addAction(setmapsizeact)\r
- setorigineact = QtGui.QAction(u"座標設定(&O)", self)\r
+ setorigineact = QtGui.QAction("座標設定(&O)", self)\r
setorigineact.triggered.connect(self.setorigine_triggered)\r
editmenu.addAction(setorigineact)\r
+ wallmenustringact = QtGui.QAction("壁メニューに文字を表示する(&W)", self)\r
+ wallmenustringact.setCheckable(True)\r
+ wallmenustringact.setChecked(config.get("showWallMenuString", False))\r
+ wallmenustringact.triggered.connect(self.togglewallmenustring_triggered)\r
+ editmenu.addAction(wallmenustringact)\r
\r
#Help menu\r
- helpmenu = self.menuBar().addMenu(u"ヘルプ(&H)")\r
- tutorialact = QtGui.QAction(u"ヘルプの表示(&H)", self)\r
+ helpmenu = self.menuBar().addMenu("ヘルプ(&H)")\r
+ tutorialact = QtGui.QAction("ヘルプの表示(&H)", self)\r
tutorialact.triggered.connect(self.tutorial_triggered)\r
tutorialact.setShortcut(QtGui.QKeySequence.HelpContents)\r
helpmenu.addAction(tutorialact)\r
- projectact = QtGui.QAction(u"プロジェクトのWebサイト(&W)", self)\r
+ projectact = QtGui.QAction("プロジェクトのWebサイト(&W)", self)\r
projectact.triggered.connect(self.project_triggered)\r
helpmenu.addAction(projectact)\r
- aboutact = QtGui.QAction(u"Pydunについて(&A)...", self)\r
+ aboutact = QtGui.QAction("Pydunについて(&A)...", self)\r
aboutact.triggered.connect(self.about_triggered)\r
helpmenu.addAction(aboutact)\r
\r
self.redoact.setDisabled(True)\r
\r
def setTitle(self, filename):\r
+ s = self.getfilename(filename) + " - Pydun"\r
+ self.setWindowTitle(s)\r
+\r
+ def getfilename(self, filename):\r
if filename == None:\r
- s = u"新規作成"\r
+ s = "無題"\r
else:\r
- s = os.path.basename(filename)\r
- s ="Pydun - " + s\r
- self.setWindowTitle(s)\r
+ s = os.path.splitext(os.path.basename(filename))[0]\r
+ return s\r
\r
@QtCore.Slot()\r
def new_triggered(self):\r
- if QtGui.QMessageBox.Ok == QtGui.QMessageBox.question(\r
- self, u"確認", u"新しいマップを作成しますか?",\r
- (QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)):\r
+ if self.confirmdiscarding():\r
self.new()\r
+ return True\r
+ return False\r
\r
def new(self):\r
global _mapengine\r
_mapengine = MapEngine(20, 20, 1, -1, 0, +19)\r
- _undomanager.clear()\r
- _undomanager.save(_mapengine.savestring())\r
+ _undomanager.init(_mapengine.savestring())\r
self.setTitle(None)\r
try:\r
self.mainframe.mapframe.repaint()\r
except:\r
pass\r
\r
+ def confirmdiscarding(self):\r
+ if not _undomanager.commited:\r
+ dlg = PydunAskSaveDialog(self, self.getfilename(_mapengine.filename))\r
+ ret = dlg.exec_()\r
+ if ret == QtGui.QMessageBox.Cancel:\r
+ return False\r
+ elif ret == QtGui.QMessageBox.Save:\r
+ saved = self.save_triggered()\r
+ if not saved:\r
+ return False\r
+ return True\r
+\r
@QtCore.Slot()\r
def open_triggered(self):\r
- d = ""\r
- try:\r
- d = os.path.dirname(_mapengine.filename)\r
- except:\r
- pass\r
- filename = QtGui.QFileDialog.getOpenFileName(\r
- dir=d,\r
- filter=u"*.pydun;;*.*", selectedFilter=u"*.pydun")\r
- if filename[0] != u"":\r
- self.open(filename[0])\r
+ if self.confirmdiscarding():\r
+ d = ""\r
+ try:\r
+ d = os.path.dirname(_mapengine.filename)\r
+ except:\r
+ pass\r
+ filename = QtGui.QFileDialog.getOpenFileName(\r
+ dir=d,\r
+ filter="*.pydun;;*.*", selectedFilter="*.pydun")\r
+ if filename[0] != "":\r
+ self.open(filename[0])\r
\r
def open(self, filename):\r
_mapengine.load(filename)\r
- _undomanager.clear()\r
- _undomanager.save(_mapengine.savestring())\r
+ _undomanager.init(_mapengine.savestring())\r
self.setTitle(_mapengine.filename)\r
try:\r
self.mainframe.mapframe.repaint()\r
def save_triggered(self):\r
if _mapengine.filename:\r
self.save(_mapengine.filename)\r
+ saved = True\r
else:\r
- self.saveas_triggered()\r
+ saved = self.saveas_triggered()\r
+ return saved\r
\r
@QtCore.Slot()\r
def saveas_triggered(self):\r
pass\r
filename = QtGui.QFileDialog.getSaveFileName(\r
dir=d,\r
- filter=u"*.pydun;;*.*", selectedFilter=u"*.pydun")\r
- if filename[0] != u"":\r
+ filter="*.pydun;;*.*", selectedFilter="*.pydun")\r
+ if filename[0] != "":\r
self.save(filename[0])\r
+ return True\r
+ else:\r
+ return False\r
\r
def save(self, filename):\r
_mapengine.save(filename)\r
+ _undomanager.commit()\r
self.setTitle(_mapengine.filename)\r
\r
@QtCore.Slot()\r
def exit(self):\r
global config\r
global configfilename\r
- if QtGui.QMessageBox.Ok == QtGui.QMessageBox.question(\r
- self, u"確認", u"終了しますか?",\r
- (QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)):\r
+ if self.confirmdiscarding():\r
config["windowSize"] = dict()\r
config["windowSize"]["width"] = self.size().width()\r
config["windowSize"]["height"] = self.size().height()\r
\r
@QtCore.Slot()\r
def setorigine_triggered(self):\r
- title = u"座標設定"\r
+ title = "座標設定"\r
if self.mainframe.mapframe.setoriginemode:\r
QtGui.QMessageBox.information(\r
- self, title, u"座標設定を中止します。", QtGui.QMessageBox.Ok)\r
+ self, title, "座標設定を中止します。", QtGui.QMessageBox.Ok)\r
self.mainframe.mapframe.setoriginemode = False\r
else:\r
if QtGui.QMessageBox.Ok == QtGui.QMessageBox.information(\r
- self, title, u"基準にする地点をクリックしてください。",\r
+ self, title, "基準にする地点をクリックしてください。",\r
(QtGui.QMessageBox.Ok| QtGui.QMessageBox.Cancel)):\r
self.mainframe.mapframe.setoriginemode = True\r
\r
self.mainframe.mapframe.repaint()\r
\r
@QtCore.Slot()\r
+ def togglewallmenustring_triggered(self):\r
+ global config\r
+ config["showWallMenuString"] = not config.get("showWallMenuString", False)\r
+ QtGui.QMessageBox.information(\r
+ self, "壁メニューに文字を表示する", "表示の切替は再起動後に有効になります。",\r
+ (QtGui.QMessageBox.Ok))\r
+\r
+ @QtCore.Slot()\r
def tutorial_triggered(self):\r
- url = os.path.dirname(os.path.abspath(__file__)) + "/help/index.html"\r
+ url = basedir() + "/help/index.html"\r
webbrowser.open_new_tab(url)\r
\r
@QtCore.Slot()\r
@QtCore.Slot()\r
def about_triggered(self):\r
QtGui.QMessageBox.about(self, "Pydun",\r
- u"<h1>Pydun.py "+ projectversion + "</h1>"\r
- u"<p>Copyright (c) 2013 WATAHIKI Hiroyuki</p>"\r
- u"<p>url: <a href='" + projecturl + "'>" + projecturl + "</a></p>"\r
- u"<p>e-mail: hrwatahiki at gmail.com</p>"\r
- u"<p>このソフトウェアはMITライセンスです。</p>"\r
- u"<p>このソフトウェアは以下のソフトウェアを使用しています。: "\r
- u"Python, PySide, PyYAML "\r
- u"これらの作成者に深く感謝いたします。</p>"\r
- u"<p>詳細はLICENCE.txtを参照してください。</p>")\r
+ "<h1>Pydun.py "+ projectversion + "</h1>"\r
+ "<p>Copyright (c) 2013 WATAHIKI Hiroyuki</p>"\r
+ "<p>url: <a href='" + projecturl + "'>" + projecturl + "</a></p>"\r
+ "<p>e-mail: hrwatahiki at gmail.com</p>"\r
+ "<p>twitter: <a href='https://twitter.com/hrwatahiki'>@hrwatahiki</a></p>"\r
+ "<p>blog: <a href='http://hrwatahiki.blogspot.jp/'>作業記録</a></p>"\r
+ "<p>このソフトウェアはMITライセンスです。</p>"\r
+ "<p>このソフトウェアは以下のソフトウェアを使用しています。: "\r
+ "Python, PySide, PyYAML "\r
+ "これらの作成者に深く感謝いたします。</p>"\r
+ "<p>詳細はLICENCE.txtを参照してください。</p>")\r
\r
\r
class MainFrame(QtGui.QFrame):\r
\r
self.detail = QtGui.QLabel(self)\r
self.detail.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)\r
- self.detail.setText(u"")\r
+ self.detail.setText("")\r
self.detail.setMaximumHeight(100)\r
self.detail.setMinimumHeight(100)\r
\r
self.boxdrawbutton = QtGui.QRadioButton(self)\r
- self.boxdrawbutton.setText(u"ボックス形式で壁を描画(&B)")\r
+ self.boxdrawbutton.setText("ボックス形式で壁を描画(&B)")\r
self.boxdrawbutton.setChecked(True)\r
self.boxdrawbutton.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
\r
self.growdrawbutton = QtGui.QRadioButton(self)\r
- self.growdrawbutton.setText(u"足跡形式で壁を描画(&G)")\r
+ self.growdrawbutton.setText("足跡形式で壁を描画(&G)")\r
self.growdrawbutton.setChecked(False)\r
self.growdrawbutton.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
\r
self.backcolorbutton = QtGui.QRadioButton(self)\r
- self.backcolorbutton.setText(u"背景色(&C)")\r
+ self.backcolorbutton.setText("背景色(&C)")\r
self.backcolorbutton.setChecked(False)\r
self.backcolorbutton.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
\r
self.setbackcolorbutton = QtGui.QPushButton(self)\r
- self.setbackcolorbutton.setText(u"背景色を設定(&S)...")\r
+ self.setbackcolorbutton.setText("背景色を設定(&S)...")\r
self.setbackcolorbutton.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
\r
self.backcolorbox.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
\r
+ latestversion = getlatestversion()\r
+ if latestversion != projectversion:\r
+ self.update = QtGui.QLabel(self)\r
+ self.update.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)\r
+ self.update.setText("<a href='{url}'>最新のPydun({ver})がダウンロードできます。</a>".format(url=projecturl, ver=latestversion))\r
+ self.update.setOpenExternalLinks(True)\r
\r
layout = QtGui.QGridLayout(self)\r
layout.addWidget(scrollarea, 0, 0, 1, 3)\r
layout.addWidget(self.backcolorbutton, 3, 1, 1, 2)\r
layout.addWidget(self.setbackcolorbutton, 4, 1, 1, 1)\r
layout.addWidget(self.backcolorbox, 4, 2, 1, 1)\r
+ if latestversion != projectversion:\r
+ layout.addWidget(self.update, 5, 0, 1, 3)\r
\r
self.setLayout(layout)\r
\r
def create_wall_menu(self, direction):\r
menu = QtGui.QMenu(self)\r
for idx, img in enumerate(_mapimages.wall_icons):\r
- act = QtGui.QAction(self)\r
+ act = QtGui.QAction(_mapimages.wall_texts[idx][direction], self)\r
act.setIcon(img[direction])\r
\r
def triggerd(idx):\r
\r
@QtCore.Slot(int, int, int)\r
def mouse_moved(self, x=0, y=0, b=QtCore.Qt.MouseButton.NoButton):\r
- cood = u"({x}, {y})\n".format(x=_mapengine.viewx(x), y=_mapengine.viewy(y))\r
+ cood = "({x}, {y})\n".format(x=_mapengine.viewx(x), y=_mapengine.viewy(y))\r
self.detail.setText(cood + _mapengine.getdetail(x, y))\r
self.mapframe.repaint()\r
\r
global config\r
dlg = PydunColorDialog(self, config.get("customColor", dict()))\r
dlg.setCurrentColor(self.backcolorbox.color)\r
- dlg.exec_(config)\r
+ dlg.exec_()\r
+ config["customColor"] = dlg.config\r
if dlg.result() == QtGui.QDialog.Accepted:\r
self.backcolorbox.color = dlg.currentColor()\r
self.backcolorbutton.setChecked(True)\r
def paintEvent(self, event):\r
painter = QtGui.QPainter(self)\r
painter.fillRect(0, 0, self.width(), self.height(), QtGui.QColor(255, 255, 255))\r
- w = _mapimages.width\r
- v = _mapimages.height\r
+ w = _mapimages.width - 1\r
+ v = _mapimages.height - 1\r
ho = _mapimages.heightoffset\r
wo = _mapimages.widthoffset\r
\r
#エリアサイズを再計算\r
self.resize(\r
- _mapimages.width * (_mapengine.width) + _mapimages.widthoffset * 2,\r
- _mapimages.height * (_mapengine.height) + _mapimages.heightoffset * 2\r
+ w * (_mapengine.width) + _mapimages.widthoffset * 2,\r
+ v * (_mapengine.height) + _mapimages.heightoffset * 2\r
)\r
\r
#backcolor\r
painter.fillRect(wo + xx, ho + yy, w, v,\r
getcolorfromstring(backcolor))\r
\r
- #wall\r
+ #grid\r
for x in range(_mapengine.width + 1):\r
xx = x * w\r
for y in range(_mapengine.height + 1):\r
yy = y * v\r
if x != _mapengine.width:\r
painter.drawImage(wo + xx, yy,\r
- _mapimages.wall(_mapengine.getdata(x, y, "h"), "h"))\r
+ _mapimages.wall(0, "h"))\r
if y != _mapengine.height:\r
painter.drawImage(xx, ho + yy,\r
+ _mapimages.wall(0, "v"))\r
+\r
+ #wall(gridは描画しない)\r
+ for x in range(_mapengine.width + 1):\r
+ xx = x * w\r
+ for y in range(_mapengine.height + 1):\r
+ yy = y * v\r
+ if x != _mapengine.width and _mapengine.getdata(x, y, "h") != 0:\r
+ painter.drawImage(wo + xx, yy,\r
+ _mapimages.wall(_mapengine.getdata(x, y, "h"), "h"))\r
+ if y != _mapengine.height and _mapengine.getdata(x, y, "v") != 0:\r
+ painter.drawImage(xx, ho + yy,\r
_mapimages.wall(_mapengine.getdata(x, y, "v"), "v"))\r
mark = _mapengine.getmark(x, y)\r
if mark != "":\r
painter.setPen(getcolorfromstring(_mapengine.getforecolor(x, y)))\r
- painter.drawText(wo + xx + 1, ho + yy + 1, w - 2, v - 2,\r
+ painter.drawText(wo + xx + 2, ho + yy + 2, w - 2, v - 2,\r
QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter,\r
mark)\r
\r
\r
def eventFilter(self, obj, event):\r
def xpos():\r
- return ((event.pos().x() - _mapimages.widthoffset) // _mapimages.width)\r
+ return ((event.pos().x() - _mapimages.widthoffset) // (_mapimages.width - 1))\r
\r
def ypos():\r
- return ((event.pos().y() - _mapimages.heightoffset) // _mapimages.height)\r
+ return ((event.pos().y() - _mapimages.heightoffset) // (_mapimages.height - 1))\r
\r
if obj == self:\r
et = event.type()\r
self.mouse_drag_released.emit(\r
self._x1, self._y1, self._x2, self._y2, eraseonly)\r
if release_emit:\r
- rpx = self._px2 - self._x2 * _mapimages.width - _mapimages.widthoffset\r
- rpy = self._py2 - self._y2 * _mapimages.height - _mapimages.heightoffset\r
- if rpx <= _mapimages.widthoffset:\r
+ rpx = self._px2 - self._x2 * (_mapimages.width - 1) - _mapimages.widthoffset\r
+ rpy = self._py2 - self._y2 * (_mapimages.height - 1) - _mapimages.heightoffset\r
+ rdx = rpx - (_mapimages.width - 1) // 2\r
+ rdy = rpy - (_mapimages.height - 1) // 2\r
+ if rpx <= _mapimages.widthoffset and abs(rdx) > abs(rdy):\r
rx = self._x2\r
ry = self._y2\r
d = "v"\r
- elif rpx >= _mapimages.width - _mapimages.widthoffset:\r
+ elif rpx >= _mapimages.width - _mapimages.widthoffset and abs(rdx) > abs(rdy):\r
rx = self._x2 + 1\r
ry = self._y2\r
d = "v"\r
- elif rpy <= _mapimages.heightoffset:\r
+ elif rpy <= _mapimages.heightoffset and abs(rdx) <= abs(rdy):\r
rx = self._x2\r
ry = self._y2\r
d = "h"\r
- elif rpy >= _mapimages.height - _mapimages.heightoffset:\r
+ elif rpy >= _mapimages.height - _mapimages.heightoffset and abs(rdx) <= abs(rdy):\r
rx = self._x2\r
ry = self._y2 + 1\r
d = "h"\r
\r
marklabel = QtGui.QLabel(self)\r
marklabel.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight)\r
- marklabel.setText(u"マーク(&M)")\r
+ marklabel.setText("マーク(&M)")\r
marklabel.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
\r
self.marktext = QtGui.QLineEdit(self)\r
self.marktext.setMaxLength(1)\r
- self.marktext.setText(u"")\r
+ self.marktext.setText("")\r
self.marktext.setMinimumWidth(20)\r
self.marktext.setSizePolicy(\r
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)\r
marklabel.setBuddy(self.marktext)\r
\r
self.forecolorbutton = QtGui.QPushButton(self)\r
- self.forecolorbutton.setText(u"文字色(&C)...")\r
+ self.forecolorbutton.setText("文字色(&C)...")\r
self.forecolorbutton.clicked.connect(self.forecolorbutton_clicked)\r
\r
self.forecolorbox = ColorBox(self)\r
\r
detaillabel = QtGui.QLabel(self)\r
detaillabel.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignRight)\r
- detaillabel.setText(u"詳細(&D)")\r
+ detaillabel.setText("詳細(&D)")\r
\r
self.detailtext = QtGui.QTextEdit(self)\r
- self.detailtext.setText(u"")\r
+ self.detailtext.setText("")\r
detaillabel.setBuddy(self.detailtext)\r
\r
- self.buttonBox = QtGui.QDialogButtonBox(\r
+ self.buttonbox = QtGui.QDialogButtonBox(\r
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)\r
- self.buttonBox.accepted.connect(self.accept)\r
- self.buttonBox.rejected.connect(self.reject)\r
+ self.buttonbox.accepted.connect(self.accept)\r
+ self.buttonbox.rejected.connect(self.reject)\r
+ self.buttonbox.button(QtGui.QDialogButtonBox.Ok).setText("OK")\r
+ self.buttonbox.button(QtGui.QDialogButtonBox.Cancel).setText("キャンセル")\r
\r
layout = QtGui.QGridLayout()\r
layout.addWidget(marklabel, 0, 0, 1, 1)\r
layout.addWidget(self.forecolorbox, 0, 3, 1, 1)\r
layout.addWidget(detaillabel, 1, 0, 1, 1)\r
layout.addWidget(self.detailtext, 1, 1, 1, 3)\r
- layout.addWidget(self.buttonBox, 2, 0, 1, 4)\r
+ layout.addWidget(self.buttonbox, 2, 0, 1, 4)\r
self.setLayout(layout)\r
self.setModal(True)\r
\r
def setvalue(self, x, y, mark, detail, color):\r
- self.setWindowTitle("({x},{y})".format(x=x, y=y))\r
+ self.setWindowTitle("({x}, {y})".format(x=x, y=y))\r
self.marktext.setText(mark)\r
self.detailtext.setText(detail)\r
self.forecolorbox.color = color\r
global config\r
dlg = PydunColorDialog(self, config.get("customColor", dict()))\r
dlg.setCurrentColor(self.forecolorbox.color)\r
- dlg.exec_(config)\r
+ dlg.exec_()\r
+ config["customColor"] = dlg.config\r
if dlg.result() == QtGui.QDialog.Accepted:\r
self.forecolorbox.color = dlg.currentColor()\r
\r
+\r
class SetOrigineDialog(QtGui.QDialog):\r
def __init__(self, parent=None):\r
super(SetOrigineDialog, self).__init__(parent)\r
- self.setWindowTitle(u"座標設定")\r
+ self.setWindowTitle("座標設定")\r
\r
promptlabel = QtGui.QLabel(self)\r
promptlabel.setAlignment(\r
QtCore.Qt.AlignVCenter | QtCore.Qt.AlignLeft)\r
- promptlabel.setText(u"この地点の座標を入力してください。")\r
+ promptlabel.setText("この地点の座標を入力してください。")\r
\r
self.currentlabel = QtGui.QLabel(self)\r
self.currentlabel.setAlignment(\r
QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)\r
- self.currentlabel.setText(u"")\r
+ self.currentlabel.setText("")\r
\r
xlabel = QtGui.QLabel(self)\r
xlabel.setAlignment(\r
QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight)\r
- xlabel.setText(u"&X")\r
+ xlabel.setText("&X")\r
\r
self.xbox = QtGui.QSpinBox(self)\r
self.xbox.setRange(-999, +999)\r
\r
ylabel = QtGui.QLabel(self)\r
ylabel.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight)\r
- ylabel.setText(u"&Y")\r
+ ylabel.setText("&Y")\r
\r
self.ybox = QtGui.QSpinBox(self)\r
self.ybox.setRange(-999, +999)\r
self.ybox.setValue(0)\r
ylabel.setBuddy(self.ybox)\r
\r
- self.buttonBox = QtGui.QDialogButtonBox(\r
+ self.buttonbox = QtGui.QDialogButtonBox(\r
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)\r
- self.buttonBox.accepted.connect(self.accept)\r
- self.buttonBox.rejected.connect(self.reject)\r
+ self.buttonbox.accepted.connect(self.accept)\r
+ self.buttonbox.rejected.connect(self.reject)\r
+ self.buttonbox.button(QtGui.QDialogButtonBox.Ok).setText("OK")\r
+ self.buttonbox.button(QtGui.QDialogButtonBox.Cancel).setText("キャンセル")\r
\r
layout = QtGui.QGridLayout()\r
layout.addWidget(promptlabel, 0, 0, 1, 4)\r
layout.addWidget(self.xbox, 2, 1, 1, 1)\r
layout.addWidget(ylabel, 2, 2, 1, 1)\r
layout.addWidget(self.ybox, 2, 3, 1, 1)\r
- layout.addWidget(self.buttonBox, 3, 0, 1, 4)\r
+ layout.addWidget(self.buttonbox, 3, 0, 1, 4)\r
self.setLayout(layout)\r
self.setModal(True)\r
\r
def setcurrent(self, x, y):\r
self.xbox.setValue(x)\r
self.ybox.setValue(y)\r
- self.currentlabel.setText(u"現在の座標 ({x}, {y})".format(x=x, y=y))\r
+ self.currentlabel.setText("現在の座標 ({x}, {y})".format(x=x, y=y))\r
\r
@property\r
def originex(self):\r
class SetSizeDialog(QtGui.QDialog):\r
def __init__(self, parent=None):\r
super(SetSizeDialog, self).__init__(parent)\r
- self.setWindowTitle(u"マップのサイズ")\r
+ self.setWindowTitle("マップのサイズ")\r
\r
self.topbutton = QtGui.QRadioButton(self)\r
- self.topbutton.setText(u"上(&T)")\r
+ self.topbutton.setText("上(&T)")\r
self.topbutton.clicked.connect(self.updatewidgets)\r
\r
self.topsize = QtGui.QSpinBox(self)\r
self.topsize.valueChanged.connect(self.updatewidgets)\r
\r
self.bottombutton = QtGui.QRadioButton(self)\r
- self.bottombutton.setText(u"下(&B)")\r
+ self.bottombutton.setText("下(&B)")\r
self.bottombutton.clicked.connect(self.updatewidgets)\r
\r
self.bottomsize = QtGui.QSpinBox(self)\r
self.bottomsize.valueChanged.connect(self.updatewidgets)\r
\r
self.leftbutton = QtGui.QRadioButton(self)\r
- self.leftbutton.setText(u"左(&L)")\r
+ self.leftbutton.setText("左(&L)")\r
self.leftbutton.clicked.connect(self.updatewidgets)\r
\r
self.leftsize = QtGui.QSpinBox(self)\r
self.leftsize.valueChanged.connect(self.updatewidgets)\r
\r
self.rightbutton = QtGui.QRadioButton(self)\r
- self.rightbutton.setText(u"右(&R)")\r
+ self.rightbutton.setText("右(&R)")\r
self.rightbutton.clicked.connect(self.updatewidgets)\r
\r
self.rightsize = QtGui.QSpinBox(self)\r
self.sizelabel = QtGui.QLabel(self)\r
self.sizelabel .setAlignment(\r
QtCore.Qt.AlignVCenter | QtCore.Qt.AlignLeft)\r
- self.sizelabel.setText(u"この地点の座標を入力してください。")\r
+ self.sizelabel.setText("この地点の座標を入力してください。")\r
\r
self.buttonbox = QtGui.QDialogButtonBox(\r
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)\r
self.buttonbox.accepted.connect(self.accept)\r
self.buttonbox.rejected.connect(self.reject)\r
+ self.buttonbox.button(QtGui.QDialogButtonBox.Ok).setText("OK")\r
+ self.buttonbox.button(QtGui.QDialogButtonBox.Cancel).setText("キャンセル")\r
\r
verticalgroup = QtGui.QButtonGroup(self)\r
verticalgroup.addButton(self.topbutton)\r
self.rightsize.setEnabled(True)\r
\r
self.sizelabel.setText(\r
- u"変更前のサイズ: {w1} x {h1}\n変更後のサイズ: {w2} x {h2}".format(\r
+ "変更前のサイズ: {w1} x {h1}\n変更後のサイズ: {w2} x {h2}".format(\r
w1=self._width, h1=self._height,\r
w2=self._width+dw, h2=self._height+dh))\r
\r
\r
\r
class MapImages(object):\r
- def __init__(self):\r
+ def __init__(self, show_wall_menu_string):\r
+ if show_wall_menu_string:\r
+ vtext = ["なし", "壁", "扉", "扉(→)", "扉(←)", "一通(→)", "一通(←)", "隠", "隠(→)", "隠(←)",]\r
+ htext = ["なし", "壁", "扉", "扉(↓)", "扉(↑)", "一通(↓)", "一通(↑)", "隠", "隠(↓)", "隠(↑)",]\r
+ else:\r
+ vtext = ["", "", "", "", "", "", "", "", "", "",]\r
+ htext = ["", "", "", "", "", "", "", "", "", "",]\r
self.wall_images = list()\r
self.wall_icons = list()\r
+ self.wall_texts = list()\r
for index in range(10):\r
self.wall_images.append(dict())\r
self.wall_icons.append(dict())\r
+ self.wall_texts.append(dict())\r
for direction in ["v", "h"]:\r
filename = os.path.join(\r
- os.path.dirname(os.path.abspath(__file__)),\r
- u"images",\r
- u"wall_{direction}_{index:02}.png".format(\r
+ basedir(),\r
+ "images",\r
+ "wall_{direction}_{index:02}.png".format(\r
direction=direction, index=index))\r
self.wall_images[index][direction] = QtGui.QImage()\r
self.wall_images[index][direction].load(filename)\r
self.wall_icons[index][direction] = QtGui.QIcon(filename)\r
+ self.wall_texts[index]["v"] = vtext[index]\r
+ self.wall_texts[index]["h"] = htext[index]\r
\r
@property\r
def width(self):\r
def represent_unicode(dumper, data):\r
return dumper.represent_scalar("tag:yaml.org,2002:str", data)\r
def construct_unicode(loader, node):\r
- return unicode(loader.construct_scalar(node))\r
- yaml.add_representer(unicode, represent_unicode)\r
+ return str(loader.construct_scalar(node))\r
+ yaml.add_representer(str, represent_unicode)\r
yaml.add_constructor("tag:yaml.org,2002:str", construct_unicode)\r
\r
def getdata(self, x, y, direction):\r
\r
def getnote(self, x, y):\r
return self._note.get(\r
- self.coodtokey(x, y), {"mark":u"", "detail":u"", "forecolor":u"#000000", "backcolor":u""})\r
+ self.coodtokey(x, y), {"mark":"", "detail":"", "forecolor":"#000000", "backcolor":""})\r
\r
def coodtokey(self, x, y):\r
- return u"{x:+05d}_{y:+05d}".format(x=x, y=y)\r
+ return "{x:+05d}_{y:+05d}".format(x=int(x), y=int(y))\r
\r
def keytocood(self, key):\r
- return map(int, key.split("_"))\r
+ return list(map(int, key.split("_")))\r
\r
def setmark(self, x, y, mark):\r
note = self.getnote(x, y)\r
\r
def save(self, filename):\r
dt = self.savestring()\r
- with codecs.open(filename, "w") as f:\r
+ with open(filename, "w", encoding='utf-8') as f:\r
f.write(dt)\r
self.filename = filename\r
\r
\r
#noteは表示用に座標変換する。\r
n = dict()\r
- for nk, ni in self._note.items():\r
+ for nk, ni in list(self._note.items()):\r
if ni["mark"] != "" or ni["detail"] != "" or ni["backcolor"]:\r
x, y = self.keytocood(nk)\r
n[self.coodtokey(self.viewx(x), self.viewy(y))] = ni\r
data["note"] = n\r
return yaml.safe_dump(data, allow_unicode=True,\r
- default_flow_style=False, encoding='utf-8')\r
+ default_flow_style=False, encoding='utf-8').decode('utf-8')\r
\r
def getmapstring(self):\r
#出力用マップ作成\r
return m\r
\r
def load(self, filename):\r
- with codecs.open(filename, "r", encoding="utf-8") as f:\r
+ with open(filename, "r", encoding="utf-8") as f:\r
st = f.read()\r
self.loadfromstring(st)\r
self.filename = filename\r
\r
#noteは内部用に座標変換する。\r
n = dict()\r
- for nk, ni in data["note"].items():\r
+ for nk, ni in list(data["note"].items()):\r
if ni["mark"] != "" or ni["detail"] != "" or ni["backcolor"] != "":\r
x, y = self.keytocood(nk)\r
n[self.coodtokey(self.worldx(x), self.worldy(y))] = ni\r
self._undo = [None for x in range(self.MAX_UNDO_COUNT)]\r
self._index = 0\r
self._undocount = 0\r
+ self._commited = True\r
self.changed.emit(self.canundo, self.canredo)\r
\r
+ def init(self, data):\r
+ self.clear()\r
+ self.save(data)\r
+ self._commited = True\r
+\r
def save(self, obj):\r
if self._index >= self.MAX_UNDO_COUNT:\r
self._undo = self._undo[1:]\r
self._undo[self._index] = obj\r
self._index += 1\r
self._undocount = 0\r
+ self._commited = False\r
self.changed.emit(self.canundo, self.canredo)\r
\r
def undo(self):\r
self._index -= 1\r
self._undocount += 1\r
+ self._commited = False\r
self.changed.emit(self.canundo, self.canredo)\r
return self._undo[self._index - 1]\r
\r
def redo(self):\r
self._index += 1\r
self._undocount -= 1\r
+ self._commited = False\r
self.changed.emit(self.canundo, self.canredo)\r
return self._undo[self._index - 1]\r
\r
+ def commit(self):\r
+ self._commited = True\r
+\r
@property\r
def canundo(self):\r
return (self._index > 1)\r
def canredo(self):\r
return (self._undocount > 0)\r
\r
+ @property\r
+ def commited(self):\r
+ return self._commited\r
+\r
\r
class PydunColorDialog(QtGui.QColorDialog):\r
def __init__(self, parent, config):\r
self.setCustomColor(index,\r
getcolorfromstring(\r
config.get(index, "#FFFFFF")).rgb())\r
+ self.updateconfig()\r
\r
- def exec_(self, config):\r
- super(PydunColorDialog, self).exec_()\r
- config = dict()\r
+ def updateconfig(self):\r
+ self._config = dict()\r
for index in range(self.customCount()):\r
- config[index] = getcolorstring(\r
+ self._config[index] = getcolorstring(\r
QtGui.QColor.fromRgb(self.customColor(index)))\r
\r
+ def exec_(self):\r
+ super(PydunColorDialog, self).exec_()\r
+ self.updateconfig()\r
+\r
+ @property\r
+ def config(self):\r
+ return self._config\r
+\r
+\r
+class PydunAskSaveDialog(QtGui.QMessageBox):\r
+ def __init__(self, parent, filename):\r
+ super(PydunAskSaveDialog, self).__init__(parent)\r
+ self.setText("{filename} への変更を保存しますか?".format(filename=filename))\r
+ self.setStandardButtons(QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel)\r
+ self.setDefaultButton(QtGui.QMessageBox.Save)\r
+ self.button(QtGui.QMessageBox.Save).setText("保存する(&S)")\r
+ self.button(QtGui.QMessageBox.Discard).setText("保存しない(&N)")\r
+ self.button(QtGui.QMessageBox.Cancel).setText("キャンセル")\r
+\r
\r
def getcolorstring(color):\r
return "#{r:02x}{g:02x}{b:02x}".format(r=color.red(), g=color.green(), b=color.blue())\r
int(colorstring[3:5], 16),\r
int(colorstring[5:7], 16))\r
\r
+def basedir():\r
+ return os.path.dirname(os.path.abspath(sys.argv[0]))\r
+\r
+def getlatestversion():\r
+ try:\r
+ rss = urllib.request.urlopen(projectrssurl)\r
+ rssstring = rss.read()\r
+ rsstree = xml.etree.ElementTree.fromstring(rssstring)\r
+ item = rsstree.find("channel/item/title")\r
+ ver = (item.text.split(" "))[2]\r
+ rss.close()\r
+ except:\r
+ ver = projectversion\r
+ return ver\r
+\r
\r
def main():\r
loadconfig()\r
global config\r
global configfilename\r
configfilename = os.path.join(\r
- os.path.dirname(os.path.abspath(__file__)),\r
- u"Pydun.config")\r
+ basedir(),\r
+ "Pydun.config")\r
try:\r
with open(configfilename, "r") as f:\r
config = yaml.safe_load(f)\r