mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
* improved support GTK (alpha)
git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@49 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
2fcfcf8e99
commit
7b10c8f9ed
13 changed files with 834 additions and 206 deletions
|
@ -305,7 +305,7 @@ class PysolMenubarActions:
|
||||||
self.setMenuState(ms.redo, "edit.redo")
|
self.setMenuState(ms.redo, "edit.redo")
|
||||||
self.setMenuState(ms.redo, "edit.redoall")
|
self.setMenuState(ms.redo, "edit.redoall")
|
||||||
self.updateBookmarkMenuState()
|
self.updateBookmarkMenuState()
|
||||||
self.setMenuState(ms.restart, "edit.restartgame")
|
self.setMenuState(ms.restart, "edit.restart")
|
||||||
# Game menu
|
# Game menu
|
||||||
self.setMenuState(ms.deal, "game.dealcards")
|
self.setMenuState(ms.deal, "game.dealcards")
|
||||||
self.setMenuState(ms.autodrop, "game.autodrop")
|
self.setMenuState(ms.autodrop, "game.autodrop")
|
||||||
|
|
|
@ -1001,7 +1001,7 @@ class Game:
|
||||||
if self.app.debug and not self.top.winfo_ismapped():
|
if self.app.debug and not self.top.winfo_ismapped():
|
||||||
return
|
return
|
||||||
#self.top.busyUpdate()
|
#self.top.busyUpdate()
|
||||||
self.canvas.after(200)
|
##self.canvas.after(200)
|
||||||
self.canvas.update_idletasks()
|
self.canvas.update_idletasks()
|
||||||
old_a = self.app.opt.animations
|
old_a = self.app.opt.animations
|
||||||
if old_a == 0:
|
if old_a == 0:
|
||||||
|
|
|
@ -160,9 +160,7 @@ def helpHTML(app, document, dir_, top=None):
|
||||||
wm_set_icon(top, app.dataloader.findIcon())
|
wm_set_icon(top, app.dataloader.findIcon())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
viewer = tkHTMLViewer(top)
|
viewer = tkHTMLViewer(top, app, help_html_index)
|
||||||
viewer.app = app
|
|
||||||
viewer.home = help_html_index
|
|
||||||
viewer.display(doc)
|
viewer.display(doc)
|
||||||
#wm_map(top, maximized=maximized)
|
#wm_map(top, maximized=maximized)
|
||||||
viewer.parent.tkraise()
|
viewer.parent.tkraise()
|
||||||
|
|
|
@ -78,116 +78,130 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
def createMenubar(self):
|
def createMenubar(self):
|
||||||
|
|
||||||
entries = (
|
entries = (
|
||||||
('New', gtk.STOCK_NEW, '_New', 'N', 'New game', self.mNewGame),
|
('new', gtk.STOCK_NEW, '_New', 'N', 'New game', self.mNewGame),
|
||||||
('Open', gtk.STOCK_OPEN, '_Open', '<control>O', 'Open a\nsaved game', self.mOpen),
|
('open', gtk.STOCK_OPEN, '_Open', '<control>O', 'Open a\nsaved game', self.mOpen),
|
||||||
('Restart', gtk.STOCK_REFRESH, '_Restart', '<control>G', 'Restart the\ncurrent game', self.mRestart),
|
('restart', gtk.STOCK_REFRESH, '_Restart', '<control>G', 'Restart the\ncurrent game', self.mRestart),
|
||||||
('Save', gtk.STOCK_SAVE, '_Save', '<control>S', 'Save game', self.mSave),
|
('save', gtk.STOCK_SAVE, '_Save', '<control>S', 'Save game', self.mSave),
|
||||||
('Undo', gtk.STOCK_UNDO, 'Undo', 'Z', 'Undo', self.mUndo),
|
('undo', gtk.STOCK_UNDO, 'Undo', 'Z', 'Undo', self.mUndo),
|
||||||
('Redo', gtk.STOCK_REDO, 'Redo', 'R', 'Redo', self.mRedo),
|
('redo', gtk.STOCK_REDO, 'Redo', 'R', 'Redo', self.mRedo),
|
||||||
('Autodrop',gtk.STOCK_JUMP_TO, '_Auto drop', 'A', 'Auto drop', self.mDrop),
|
('autodrop',gtk.STOCK_JUMP_TO, '_Auto drop', 'A', 'Auto drop', self.mDrop),
|
||||||
('Stats', gtk.STOCK_EXECUTE, 'Stats', None, 'Statistics', self.mStatus),
|
('stats', gtk.STOCK_HOME, 'Stats', None, 'Statistics', self.mStatus),
|
||||||
('Rules', gtk.STOCK_HELP, 'Rules', None, 'Rules', self.mHelpRules),
|
('rules', gtk.STOCK_HELP, 'Rules', 'F1', 'Rules', self.mHelpRules),
|
||||||
('Quit', gtk.STOCK_QUIT, 'Quit', '<control>Q', 'Quit PySol', self.mQuit),
|
('quit', gtk.STOCK_QUIT, 'Quit', '<control>Q', 'Quit PySol', self.mQuit),
|
||||||
|
|
||||||
("FileMenu", None, "_File" ),
|
('file', None, '_File' ),
|
||||||
("SelectGame", None, "Select _game"),
|
('selectgame', None, 'Select _game'),
|
||||||
("EditMenu", None, '_Edit'),
|
('edit', None, '_Edit'),
|
||||||
("GameMenu", None, "_Game"),
|
('game', None, '_Game'),
|
||||||
("AssistMenu", None, "_Assist"),
|
('assist', None, '_Assist'),
|
||||||
("OptionsMenu", None, "_Options"),
|
('options', None, '_Options'),
|
||||||
('AnimationsMenu', None, '_Animations'),
|
("automaticplay", None, "_Automatic play"),
|
||||||
("HelpMenu", None, "_Help"),
|
|
||||||
|
|
||||||
('SelectGameByNumber', None, "Select game by number...", None, None, self.mSelectGameById),
|
('animations', None, '_Animations'),
|
||||||
("SaveAs", None, 'Save _as...', None, None, self.m),
|
('help', None, '_Help'),
|
||||||
("RedoAll", None, 'Redo _all', None, None, self.mRedoAll),
|
|
||||||
("DealCards", None, '_Deal cards', "D", None, self.mDeal),
|
('selectgamebynumber', None, 'Select game by number...', None, None, self.mSelectGameById),
|
||||||
("Status", None, 'S_tatus...', "T", None, self.mStatus),
|
('saveas', None, 'Save _as...', None, None, self.m),
|
||||||
("Hint", None, '_Hint', "H", None, self.mHint),
|
('redoall', None, 'Redo _all', None, None, self.mRedoAll),
|
||||||
("HighlightPiles", None, 'Highlight _piles', None, None, self.mHighlightPiles),
|
('dealcards', None, '_Deal cards', 'D', None, self.mDeal),
|
||||||
("Demo", None, '_Demo', "<control>D", None, self.mDemo),
|
('status', None, 'S_tatus...', 'T', None, self.mStatus),
|
||||||
("DemoAllGames", None, 'Demo (all games)', None, None, self.mMixedDemo),
|
('hint', None, '_Hint', 'H', None, self.mHint),
|
||||||
("TableTile", None, "Table t_ile...", None, None, self.mOptTableTile),
|
('highlightpiles', None, 'Highlight _piles', None, None, self.mHighlightPiles),
|
||||||
("Contents", None, '_Contents', 'F1', None, self.mHelp),
|
('demo', None,'_Demo', '<control>D',None,self.mDemo),
|
||||||
("About", None, '_About PySol...', None, None, self.mHelpAbout),
|
('demoallgames', None,'Demo (all games)', None,None,self.mMixedDemo),
|
||||||
|
('playeroptions',None,'_Player options...',None,None,self.mOptPlayerOptions),
|
||||||
|
('tabletile', None,'Table t_ile...', None,None,self.mOptTableTile),
|
||||||
|
('contents', None,'_Contents','<control>F1',None,self.mHelp),
|
||||||
|
('aboutpysol', None,'_About PySol...', None,None,self.mHelpAbout),
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
toggle_entries = (
|
toggle_entries = (
|
||||||
("Confirm", None, '_Confirm', None, None, self.mOptConfirm),
|
('pause', gtk.STOCK_STOP, '_Pause', 'P', 'Pause game', self.mPause),
|
||||||
("Autoplay", None, 'Auto_play', "P", None, self.mOptAutoDrop),
|
('optautodrop', None, 'A_uto drop', None, None, self.mOptAutoDrop),
|
||||||
("AutomaticFaceUp", None,'_Automatic _face up', "F", None, self.mOptAutoFaceUp),
|
('autofaceup', None, 'Auto _face up', None, None, self.mOptAutoFaceUp),
|
||||||
("HighlightMatchingCards", None, 'Highlight _matching cards', None, None, self.mOptEnableHighlightCards),
|
("autodeal", None, "Auto _deal", None, None, self.mOptAutoDeal),
|
||||||
("CardShadow", None, 'Card shadow', None, None, self.mOptShadow),
|
("quickplay", None, '_Quick play', None, None, self.mOptQuickPlay),
|
||||||
("ShadeLegalMoves", None, 'Shade legal moves', None, None, self.mOptShade),
|
|
||||||
|
('highlightmatchingcards', None, 'Highlight _matching cards', None, None, self.mOptEnableHighlightCards),
|
||||||
|
('cardshadow', None, 'Card shadow', None, None, self.mOptShadow),
|
||||||
|
('shadelegalmoves', None, 'Shade legal moves', None, None, self.mOptShade),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
animations_entries = (
|
animations_entries = (
|
||||||
("AnimationNone", None, "_None", None, None, 0),
|
('animationnone', None, '_None', None, None, 0),
|
||||||
("AnimationFast", None, "_Fast", None, None, 1),
|
('animationfast', None, '_Fast', None, None, 1),
|
||||||
("AnimationTimer", None, "_Timer based", None, None, 2),
|
('animationtimer', None, '_Timer based', None, None, 2),
|
||||||
("AnimationSlow", None, "_Slow", None, None, 3),
|
('animationslow', None, '_Slow', None, None, 3),
|
||||||
("AnimationVerySlow", None, "_Very slow", None, None, 4),
|
('animationveryslow', None, '_Very slow', None, None, 4),
|
||||||
)
|
)
|
||||||
#
|
#
|
||||||
ui_info = '''<ui>
|
ui_info = '''<ui>
|
||||||
<menubar name='MenuBar'>
|
<menubar name='menubar'>
|
||||||
|
|
||||||
<menu action='FileMenu'>
|
<menu action='file'>
|
||||||
<menuitem action='SelectGameByNumber'/>
|
<menuitem action='selectgamebynumber'/>
|
||||||
<menu action='SelectGame'/>
|
<menu action='selectgame'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action='Open'/>
|
<menuitem action='open'/>
|
||||||
<menuitem action='Save'/>
|
<menuitem action='save'/>
|
||||||
<menuitem action='SaveAs'/>
|
<menuitem action='saveas'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action='Quit'/>
|
<menuitem action='quit'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu action='EditMenu'>
|
<menu action='edit'>
|
||||||
<menuitem action='Undo'/>
|
<menuitem action='undo'/>
|
||||||
<menuitem action='Redo'/>
|
<menuitem action='redo'/>
|
||||||
<menuitem action='RedoAll'/>
|
<menuitem action='redoall'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action='Restart'/>
|
<menuitem action='restart'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu action='GameMenu'>
|
<menu action='game'>
|
||||||
<menuitem action='DealCards'/>
|
<menuitem action='dealcards'/>
|
||||||
<menuitem action='Autodrop'/>
|
<menuitem action='autodrop'/>
|
||||||
|
<menuitem action='pause'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action='Status'/>
|
<menuitem action='status'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu action='AssistMenu'>
|
<menu action='assist'>
|
||||||
<menuitem action='Hint'/>
|
<menuitem action='hint'/>
|
||||||
<menuitem action='HighlightPiles'/>
|
<menuitem action='highlightpiles'/>
|
||||||
<menuitem action='Demo'/>
|
<menuitem action='demo'/>
|
||||||
<menuitem action='DemoAllGames'/>
|
<menuitem action='demoallgames'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu action='OptionsMenu'>
|
<menu action='options'>
|
||||||
<menuitem action='Confirm'/>
|
<menuitem action='playeroptions'/>
|
||||||
<menuitem action='Autoplay'/>
|
<menu action='automaticplay'>
|
||||||
<menuitem action='AutomaticFaceUp'/>
|
<menuitem action='autofaceup'/>
|
||||||
<menuitem action='HighlightMatchingCards'/>
|
<menuitem action='autodrop'/>
|
||||||
<separator/>
|
<menuitem action='autodeal'/>
|
||||||
<menuitem action='TableTile'/>
|
<separator/>
|
||||||
<menu action='AnimationsMenu'>
|
<menuitem action='quickplay'/>
|
||||||
<menuitem action='AnimationNone'/>
|
|
||||||
<menuitem action='AnimationFast'/>
|
|
||||||
<menuitem action='AnimationTimer'/>
|
|
||||||
<menuitem action='AnimationSlow'/>
|
|
||||||
<menuitem action='AnimationVerySlow'/>
|
|
||||||
</menu>
|
</menu>
|
||||||
<menuitem action='CardShadow'/>
|
<menuitem action='highlightmatchingcards'/>
|
||||||
<menuitem action='ShadeLegalMoves'/>
|
<separator/>
|
||||||
|
<menuitem action='tabletile'/>
|
||||||
|
<menu action='animations'>
|
||||||
|
<menuitem action='animationnone'/>
|
||||||
|
<menuitem action='animationtimer'/>
|
||||||
|
<menuitem action='animationfast'/>
|
||||||
|
<menuitem action='animationslow'/>
|
||||||
|
<menuitem action='animationveryslow'/>
|
||||||
|
</menu>
|
||||||
|
<menuitem action='cardshadow'/>
|
||||||
|
<menuitem action='shadelegalmoves'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
<menu action='HelpMenu'>
|
<menu action='help'>
|
||||||
<menuitem action='Contents'/>
|
<menuitem action='contents'/>
|
||||||
<menuitem action='Rules'/>
|
<menuitem action='rules'/>
|
||||||
<menuitem action='About'/>
|
<menuitem action='aboutpysol'/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
</menubar>
|
</menubar>
|
||||||
|
@ -197,7 +211,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
ui_manager = gtk.UIManager()
|
ui_manager = gtk.UIManager()
|
||||||
ui_manager_id = ui_manager.add_ui_from_string(ui_info)
|
ui_manager_id = ui_manager.add_ui_from_string(ui_info)
|
||||||
|
|
||||||
action_group = gtk.ActionGroup("PySolActions")
|
action_group = gtk.ActionGroup('PySolActions')
|
||||||
action_group.add_actions(entries)
|
action_group.add_actions(entries)
|
||||||
action_group.add_toggle_actions(toggle_entries)
|
action_group.add_toggle_actions(toggle_entries)
|
||||||
action_group.add_radio_actions(animations_entries,
|
action_group.add_radio_actions(animations_entries,
|
||||||
|
@ -207,11 +221,11 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
ui_manager.insert_action_group(action_group, 0)
|
ui_manager.insert_action_group(action_group, 0)
|
||||||
self.top.add_accel_group(ui_manager.get_accel_group())
|
self.top.add_accel_group(ui_manager.get_accel_group())
|
||||||
self.top.ui_manager = ui_manager
|
self.top.ui_manager = ui_manager
|
||||||
menubar = ui_manager.get_widget("/MenuBar")
|
menubar = ui_manager.get_widget('/menubar')
|
||||||
|
|
||||||
games = map(self.app.gdb.get, self.app.gdb.getGamesIdSortedByName())
|
games = map(self.app.gdb.get, self.app.gdb.getGamesIdSortedByName())
|
||||||
|
|
||||||
menu_item = ui_manager.get_widget("/MenuBar/FileMenu/SelectGame")
|
menu_item = ui_manager.get_widget('/menubar/file/selectgame')
|
||||||
menu_item.show()
|
menu_item.show()
|
||||||
menu = gtk.Menu()
|
menu = gtk.Menu()
|
||||||
menu_item.set_submenu(menu)
|
menu_item.set_submenu(menu)
|
||||||
|
@ -238,7 +252,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
menu_item.connect('toggled', command, g.id)
|
menu_item.connect('toggled', command, g.id)
|
||||||
|
|
||||||
def _addSelectAllGameSubMenu(self, games, menu, command):
|
def _addSelectAllGameSubMenu(self, games, menu, command):
|
||||||
cb_max = gdk.screen_height()/20
|
cb_max = gdk.screen_height()/24
|
||||||
n, d = 0, cb_max
|
n, d = 0, cb_max
|
||||||
i = 0
|
i = 0
|
||||||
group = None
|
group = None
|
||||||
|
@ -259,15 +273,29 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
# menu updates
|
# menu updates
|
||||||
#
|
#
|
||||||
|
|
||||||
|
## WARNING: setMenuState: not found: /menubar/file/holdandquit
|
||||||
|
## WARNING: setMenuState: not found: /menubar/assist/findcard
|
||||||
def setMenuState(self, state, path):
|
def setMenuState(self, state, path):
|
||||||
return
|
path_map = {'help.rulesforthisgame': '/menubar/help/rules',}
|
||||||
w = self.__menubar.get_widget(path)
|
if path_map.has_key(path):
|
||||||
w.set_sensitive(state)
|
path = path_map[path]
|
||||||
|
else:
|
||||||
|
path = '/menubar/'+path.replace('.', '/')
|
||||||
|
menuitem = self.top.ui_manager.get_widget(path)
|
||||||
|
if not menuitem:
|
||||||
|
##print 'WARNING: setMenuState: not found:', path
|
||||||
|
return
|
||||||
|
menuitem.set_sensitive(state)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setToolbarState(self, state, path):
|
def setToolbarState(self, state, path):
|
||||||
##~ w = getattr(self.app.toolbar, path + "_button")
|
path = '/toolbar/'+path
|
||||||
##~ w.set_sensitive(state)
|
button = self.top.ui_manager.get_widget(path)
|
||||||
pass
|
if not button:
|
||||||
|
print 'WARNING: setToolbarState: not found:', path
|
||||||
|
else:
|
||||||
|
button.set_sensitive(state)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -289,7 +317,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if key <= 0:
|
if key <= 0:
|
||||||
key = self.app.opt.table_color.lower()
|
key = self.app.opt.table_color.lower()
|
||||||
d = SelectTileDialogWithPreview(self.top, app=self.app,
|
d = SelectTileDialogWithPreview(self.top, app=self.app,
|
||||||
title=_("Select table background"),
|
title=_('Select table background'),
|
||||||
manager=self.app.tabletile_manager,
|
manager=self.app.tabletile_manager,
|
||||||
key=key)
|
key=key)
|
||||||
if d.status == 0 and d.button in (0, 1):
|
if d.status == 0 and d.button in (0, 1):
|
||||||
|
@ -299,9 +327,6 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
self._mOptTableTile(d.key)
|
self._mOptTableTile(d.key)
|
||||||
|
|
||||||
|
|
||||||
def mOptConfirm(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def mOptHintOptions(self, *args):
|
def mOptHintOptions(self, *args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -36,17 +36,78 @@
|
||||||
__all__ = ['PlayerOptionsDialog']
|
__all__ = ['PlayerOptionsDialog']
|
||||||
|
|
||||||
# imports
|
# imports
|
||||||
import gtk
|
import gobject, gtk
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
|
|
||||||
# Toolkit imports
|
# Toolkit imports
|
||||||
from tkwidget import MfxDialog
|
from tkwidget import MfxDialog
|
||||||
|
from pysollib.mfxutil import kwdefault
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
class PlayerOptionsDialog(MfxDialog):
|
class PlayerOptionsDialog(MfxDialog):
|
||||||
pass
|
def __init__(self, parent, title, app, **kw):
|
||||||
|
kw = self.initKw(kw)
|
||||||
|
MfxDialog.__init__(self, parent, title, **kw)
|
||||||
|
#
|
||||||
|
top_box, bottom_box = self.createVBox()
|
||||||
|
#
|
||||||
|
label = gtk.Label('Please enter your name')
|
||||||
|
label.show()
|
||||||
|
top_box.pack_start(label)
|
||||||
|
self.player_entry = gtk.Entry()
|
||||||
|
self.player_entry.show()
|
||||||
|
top_box.pack_start(self.player_entry, expand=False)
|
||||||
|
completion = gtk.EntryCompletion()
|
||||||
|
self.player_entry.set_completion(completion)
|
||||||
|
model = gtk.ListStore(gobject.TYPE_STRING)
|
||||||
|
print '>>', app.getAllUserNames()
|
||||||
|
for name in app.getAllUserNames():
|
||||||
|
iter = model.append()
|
||||||
|
model.set(iter, 0, name)
|
||||||
|
completion.set_model(model)
|
||||||
|
completion.set_text_column(0)
|
||||||
|
self.player_entry.set_text(app.opt.player)
|
||||||
|
#
|
||||||
|
self.confirm_quit_check = gtk.CheckButton(_('Confirm quit'))
|
||||||
|
self.confirm_quit_check.show()
|
||||||
|
top_box.pack_start(self.confirm_quit_check)
|
||||||
|
self.confirm_quit_check.set_active(app.opt.confirm != 0)
|
||||||
|
#
|
||||||
|
self.update_stats_check = gtk.CheckButton(_('Update statistics and logs'))
|
||||||
|
self.update_stats_check.show()
|
||||||
|
top_box.pack_start(self.update_stats_check)
|
||||||
|
self.update_stats_check.set_active(app.opt.update_player_stats != 0)
|
||||||
|
#
|
||||||
|
self.createButtons(bottom_box, kw)
|
||||||
|
self.show_all()
|
||||||
|
gtk.main()
|
||||||
|
|
||||||
|
|
||||||
|
def initKw(self, kw):
|
||||||
|
kwdefault(kw,
|
||||||
|
strings=(_('&OK'), _('&Cancel'),),
|
||||||
|
default=0,
|
||||||
|
#resizable=1,
|
||||||
|
#font=None,
|
||||||
|
padx=10, pady=10,
|
||||||
|
#width=600, height=400,
|
||||||
|
##~ buttonpadx=10, buttonpady=5,
|
||||||
|
)
|
||||||
|
return MfxDialog.initKw(self, kw)
|
||||||
|
|
||||||
|
|
||||||
|
def done(self, button):
|
||||||
|
self.button = button.get_data('user_data')
|
||||||
|
self.player = self.player_entry.get_text()
|
||||||
|
self.confirm = self.confirm_quit_check.get_active()
|
||||||
|
self.update_stats = self.update_stats_check.get_active()
|
||||||
|
self.win_animation = False
|
||||||
|
self.quit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class SelectTileDialogWithPreview(MfxDialog):
|
||||||
kw = self.initKw(kw)
|
kw = self.initKw(kw)
|
||||||
MfxDialog.__init__(self, parent, title, **kw)
|
MfxDialog.__init__(self, parent, title, **kw)
|
||||||
#
|
#
|
||||||
top_box, bottom_box = self.createBox()
|
top_box, bottom_box = self.createHBox()
|
||||||
#
|
#
|
||||||
if key is None:
|
if key is None:
|
||||||
key = manager.getSelected()
|
key = manager.getSelected()
|
||||||
|
|
|
@ -80,6 +80,7 @@ class _CanvasItem:
|
||||||
##print self, 'addtag'
|
##print self, 'addtag'
|
||||||
##~ assert isinstance(group._item, CanvasGroup)
|
##~ assert isinstance(group._item, CanvasGroup)
|
||||||
self._item.reparent(group._item)
|
self._item.reparent(group._item)
|
||||||
|
|
||||||
def dtag(self, group):
|
def dtag(self, group):
|
||||||
pass
|
pass
|
||||||
##print self, 'dtag'
|
##print self, 'dtag'
|
||||||
|
@ -88,9 +89,11 @@ class _CanvasItem:
|
||||||
|
|
||||||
def bind(self, sequence, func, add=None):
|
def bind(self, sequence, func, add=None):
|
||||||
bind(self._item, sequence, func, add)
|
bind(self._item, sequence, func, add)
|
||||||
|
|
||||||
def bbox(self):
|
def bbox(self):
|
||||||
## FIXME
|
## FIXME
|
||||||
return (0, 0, 0, 0)
|
return (0, 0, 0, 0)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
if self._item is not None:
|
if self._item is not None:
|
||||||
self._item.destroy()
|
self._item.destroy()
|
||||||
|
@ -120,15 +123,18 @@ class _CanvasItem:
|
||||||
moveTo = move
|
moveTo = move
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
self._item.show()
|
if self._item:
|
||||||
|
self._item.show()
|
||||||
def hide(self):
|
def hide(self):
|
||||||
self._item.hide()
|
if self._item:
|
||||||
|
self._item.hide()
|
||||||
|
|
||||||
def connect(self, signal, func, args):
|
def connect(self, signal, func, args):
|
||||||
##print signal
|
##print signal
|
||||||
self._item.connect('event', func, args)
|
self._item.connect('event', func, args)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MfxCanvasGroup(_CanvasItem):
|
class MfxCanvasGroup(_CanvasItem):
|
||||||
def __init__(self, canvas):
|
def __init__(self, canvas):
|
||||||
_CanvasItem.__init__(self, canvas)
|
_CanvasItem.__init__(self, canvas)
|
||||||
|
@ -153,19 +159,6 @@ class MfxCanvasImage(_CanvasItem):
|
||||||
self._item.set(pixbuf=image.pixbuf)
|
self._item.set(pixbuf=image.pixbuf)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## arrow = MfxCanvasLine(self.canvas, x1, y1, x2, y2, width=7,
|
|
||||||
## fill=self.app.opt.hintarrow_color,
|
|
||||||
## arrow="last", arrowshape=(30,30,10))
|
|
||||||
## arrow = MfxCanvasLine(game.canvas,
|
|
||||||
## coords,
|
|
||||||
## {'width': w,
|
|
||||||
## 'fill': game.app.opt.hintarrow_color,
|
|
||||||
## ##'arrow': 'last',
|
|
||||||
## ##'arrowshape': (s1, s1, s2)
|
|
||||||
## }
|
|
||||||
## )
|
|
||||||
|
|
||||||
class MfxCanvasLine(_CanvasItem):
|
class MfxCanvasLine(_CanvasItem):
|
||||||
def __init__(self, canvas, *points, **kw):
|
def __init__(self, canvas, *points, **kw):
|
||||||
_CanvasItem.__init__(self, canvas)
|
_CanvasItem.__init__(self, canvas)
|
||||||
|
@ -192,7 +185,6 @@ class MfxCanvasLine(_CanvasItem):
|
||||||
canvas.show_all()
|
canvas.show_all()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MfxCanvasRectangle(_CanvasItem):
|
class MfxCanvasRectangle(_CanvasItem):
|
||||||
def __init__(self, canvas, x1, y1, x2, y2, width, fill, outline):
|
def __init__(self, canvas, x1, y1, x2, y2, width, fill, outline):
|
||||||
_CanvasItem.__init__(self, canvas)
|
_CanvasItem.__init__(self, canvas)
|
||||||
|
@ -259,6 +251,7 @@ class MfxCanvas(gnome.canvas.Canvas):
|
||||||
# private
|
# private
|
||||||
self.__tileimage = None
|
self.__tileimage = None
|
||||||
self.__tiles = []
|
self.__tiles = []
|
||||||
|
self.__topimage = None
|
||||||
# friend MfxCanvasText
|
# friend MfxCanvasText
|
||||||
self._text_color = '#000000'
|
self._text_color = '#000000'
|
||||||
#
|
#
|
||||||
|
@ -346,6 +339,14 @@ class MfxCanvas(gnome.canvas.Canvas):
|
||||||
self.__tileimage.destroy()
|
self.__tileimage.destroy()
|
||||||
self.__tileimage = None
|
self.__tileimage = None
|
||||||
|
|
||||||
|
def hideAllItems(self):
|
||||||
|
for i in self._all_items:
|
||||||
|
i.hide()
|
||||||
|
|
||||||
|
def showAllItems(self):
|
||||||
|
for i in self._all_items:
|
||||||
|
i.show()
|
||||||
|
|
||||||
# PySol extension
|
# PySol extension
|
||||||
def findCard(self, stack, event):
|
def findCard(self, stack, event):
|
||||||
# FIXME
|
# FIXME
|
||||||
|
@ -415,11 +416,13 @@ class MfxCanvas(gnome.canvas.Canvas):
|
||||||
if not filename:
|
if not filename:
|
||||||
return False
|
return False
|
||||||
if not self.window: # not realized yet
|
if not self.window: # not realized yet
|
||||||
return False
|
self.realize()
|
||||||
|
##return False
|
||||||
|
|
||||||
self.setBackgroundImage(filename, stretch)
|
self.setBackgroundImage(filename, stretch)
|
||||||
|
|
||||||
def setBackgroundImage(self, filename, stretch):
|
def setBackgroundImage(self, filename, stretch):
|
||||||
|
print 'setBackgroundImage', filename
|
||||||
|
|
||||||
width, height = self.get_size()
|
width, height = self.get_size()
|
||||||
pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
|
pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
|
||||||
|
@ -456,8 +459,23 @@ class MfxCanvas(gnome.canvas.Canvas):
|
||||||
|
|
||||||
|
|
||||||
def setTopImage(self, image, cw=0, ch=0):
|
def setTopImage(self, image, cw=0, ch=0):
|
||||||
## FIXME
|
if self.__topimage:
|
||||||
pass
|
self.__topimage.destroy()
|
||||||
|
self.__topimage = None
|
||||||
|
if not image:
|
||||||
|
return
|
||||||
|
if type(image) is str:
|
||||||
|
pixbuf = gtk.gdk.pixbuf_new_from_file(image)
|
||||||
|
else:
|
||||||
|
pixbuf = image.pixbuf
|
||||||
|
w, h = self.get_size()
|
||||||
|
iw, ih = pixbuf.get_width(), pixbuf.get_height()
|
||||||
|
x, y = (w-iw)/2, (h-ih)/2
|
||||||
|
dx, dy = self.world_to_window(0, 0)
|
||||||
|
dx, dy = int(dx), int(dy)
|
||||||
|
self.__topimage = self.root().add(gnome.canvas.CanvasPixbuf,
|
||||||
|
pixbuf=pixbuf, x=x-dx, y=y-dy)
|
||||||
|
|
||||||
|
|
||||||
def update_idletasks(self):
|
def update_idletasks(self):
|
||||||
##print 'MfxCanvas.update_idletasks'
|
##print 'MfxCanvas.update_idletasks'
|
||||||
|
@ -465,6 +483,7 @@ class MfxCanvas(gnome.canvas.Canvas):
|
||||||
#self.show_now()
|
#self.show_now()
|
||||||
self.update_now()
|
self.update_now()
|
||||||
|
|
||||||
|
|
||||||
def grid(self, *args, **kw):
|
def grid(self, *args, **kw):
|
||||||
self.top.table.attach(self,
|
self.top.table.attach(self,
|
||||||
0, 1, 2, 3,
|
0, 1, 2, 3,
|
||||||
|
@ -485,7 +504,7 @@ class MfxCanvas(gnome.canvas.Canvas):
|
||||||
self.set_size_request(width, height)
|
self.set_size_request(width, height)
|
||||||
#self.set_size(width, height)
|
#self.set_size(width, height)
|
||||||
#self.queue_resize()
|
#self.queue_resize()
|
||||||
gobject.idle_add(self._resize, priority=gobject.PRIORITY_HIGH_IDLE)
|
#gobject.idle_add(self._resize, priority=gobject.PRIORITY_HIGH_IDLE)
|
||||||
|
|
||||||
|
|
||||||
class MfxScrolledCanvas(MfxCanvas):
|
class MfxScrolledCanvas(MfxCanvas):
|
||||||
|
|
|
@ -4,9 +4,13 @@
|
||||||
##
|
##
|
||||||
## PySol -- a Python Solitaire game
|
## PySol -- a Python Solitaire game
|
||||||
##
|
##
|
||||||
|
## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
|
||||||
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||||
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||||
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
## All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,19 +28,169 @@
|
||||||
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
##
|
##
|
||||||
## Markus F.X.J. Oberhumer
|
## Markus F.X.J. Oberhumer
|
||||||
## <markus.oberhumer@jk.uni-linz.ac.at>
|
## <markus@oberhumer.com>
|
||||||
## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html
|
## http://www.oberhumer.com/pysol
|
||||||
##
|
##
|
||||||
##---------------------------------------------------------------------------##
|
##---------------------------------------------------------------------------##
|
||||||
|
|
||||||
|
__all__ = ['tkHTMLViewer']
|
||||||
|
|
||||||
# imports
|
# imports
|
||||||
import os, sys
|
import os, sys, re, types
|
||||||
|
import htmllib, formatter
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import gtk, pango, gobject
|
||||||
|
from gtk import gdk
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
d = os.path.abspath(os.path.join(sys.path[0], '..', '..'))
|
||||||
|
sys.path.append(d)
|
||||||
|
import gettext
|
||||||
|
gettext.install('pysol', d, unicode=True)
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
|
from pysollib.mfxutil import Struct, openURL
|
||||||
|
from pysollib.settings import PACKAGE
|
||||||
|
|
||||||
# Toolkit imports
|
# Toolkit imports
|
||||||
from tkwidget import MfxDialog
|
from tkutil import bind, unbind_destroy, loadImage
|
||||||
|
from tkwidget import MfxMessageDialog
|
||||||
|
|
||||||
|
|
||||||
|
REMOTE_PROTOCOLS = ('ftp:', 'gopher:', 'http:', 'mailto:', 'news:', 'telnet:')
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class tkHTMLWriter(formatter.NullWriter):
|
||||||
|
def __init__(self, text, viewer, app):
|
||||||
|
formatter.NullWriter.__init__(self)
|
||||||
|
|
||||||
|
self.text = text # gtk.TextBuffer
|
||||||
|
self.viewer = viewer # tkHTMLViewer
|
||||||
|
|
||||||
|
self.anchor = None
|
||||||
|
self.anchor_mark = None
|
||||||
|
|
||||||
|
self.font = None
|
||||||
|
self.font_mark = None
|
||||||
|
self.indent = ''
|
||||||
|
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
data = unicode(data)
|
||||||
|
self.text.insert(self.text.get_end_iter(), data, len(data))
|
||||||
|
|
||||||
|
def anchor_bgn(self, href, name, type):
|
||||||
|
if href:
|
||||||
|
##self.text.update_idletasks() # update display during parsing
|
||||||
|
self.anchor = (href, name, type)
|
||||||
|
self.anchor_mark = self.text.get_end_iter().get_offset()
|
||||||
|
|
||||||
|
def anchor_end(self):
|
||||||
|
if self.anchor:
|
||||||
|
href = self.anchor[0]
|
||||||
|
tag_name = 'href_' + href
|
||||||
|
if self.viewer.anchor_tags.has_key(tag_name):
|
||||||
|
tag = self.viewer.anchor_tags[tag_name][0]
|
||||||
|
else:
|
||||||
|
tag = self.text.create_tag(tag_name, foreground='blue',
|
||||||
|
underline=pango.UNDERLINE_SINGLE)
|
||||||
|
self.viewer.anchor_tags[tag_name] = (tag, href)
|
||||||
|
tag.connect('event', self.viewer.anchor_event, href)
|
||||||
|
u = self.viewer.normurl(href, with_protocol=False)
|
||||||
|
if u in self.viewer.visited_urls:
|
||||||
|
tag.set_property('foreground', '#660099')
|
||||||
|
start = self.text.get_iter_at_offset(self.anchor_mark)
|
||||||
|
end = self.text.get_end_iter()
|
||||||
|
##print 'apply_tag href >>', start.get_offset(), end.get_offset()
|
||||||
|
self.text.apply_tag(tag, start, end)
|
||||||
|
|
||||||
|
self.anchor = None
|
||||||
|
|
||||||
|
def new_font(self, font):
|
||||||
|
# end the current font
|
||||||
|
if self.font:
|
||||||
|
##print 'end_font(%s)' % `self.font`
|
||||||
|
start = self.text.get_iter_at_offset(self.font_mark)
|
||||||
|
end = self.text.get_end_iter()
|
||||||
|
##print 'apply_tag font >>', start.get_offset(), end.get_offset()
|
||||||
|
self.text.apply_tag_by_name(self.font, start, end)
|
||||||
|
self.font = None
|
||||||
|
# start the new font
|
||||||
|
if font:
|
||||||
|
##print 'start_font(%s)' % `font`
|
||||||
|
self.font_mark = self.text.get_end_iter().get_offset()
|
||||||
|
if self.viewer.fontmap.has_key(font[0]):
|
||||||
|
self.font = font[0]
|
||||||
|
elif font[3]:
|
||||||
|
self.font = 'pre'
|
||||||
|
elif font[2]:
|
||||||
|
self.font = 'bold'
|
||||||
|
elif font[1]:
|
||||||
|
self.font = 'italic'
|
||||||
|
else:
|
||||||
|
self.font = None
|
||||||
|
|
||||||
|
def new_margin(self, margin, level):
|
||||||
|
self.indent = ' ' * level
|
||||||
|
|
||||||
|
def send_label_data(self, data):
|
||||||
|
##self.write(self.indent + data + ' ')
|
||||||
|
self.write(self.indent)
|
||||||
|
if data == '*': # <li>
|
||||||
|
img = self.viewer.symbols_img.get('disk')
|
||||||
|
if img:
|
||||||
|
self.text.insert_pixbuf(self.text.get_end_iter(), img)
|
||||||
|
else:
|
||||||
|
self.write('*') ##unichr(0x2022)
|
||||||
|
else:
|
||||||
|
self.write(data)
|
||||||
|
self.write(' ')
|
||||||
|
|
||||||
|
def send_paragraph(self, blankline):
|
||||||
|
self.write('\n' * blankline)
|
||||||
|
|
||||||
|
def send_line_break(self):
|
||||||
|
self.write('\n')
|
||||||
|
|
||||||
|
def send_hor_rule(self, *args):
|
||||||
|
##~ width = int(int(self.text['width']) * 0.9)
|
||||||
|
width = 70
|
||||||
|
self.write('_' * width)
|
||||||
|
self.write('\n')
|
||||||
|
|
||||||
|
def send_literal_data(self, data):
|
||||||
|
self.write(data)
|
||||||
|
|
||||||
|
def send_flowing_data(self, data):
|
||||||
|
self.write(data)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class tkHTMLParser(htmllib.HTMLParser):
|
||||||
|
def anchor_bgn(self, href, name, type):
|
||||||
|
self.formatter.flush_softspace()
|
||||||
|
htmllib.HTMLParser.anchor_bgn(self, href, name, type)
|
||||||
|
self.formatter.writer.anchor_bgn(href, name, type)
|
||||||
|
|
||||||
|
def anchor_end(self):
|
||||||
|
if self.anchor:
|
||||||
|
self.anchor = None
|
||||||
|
self.formatter.writer.anchor_end()
|
||||||
|
|
||||||
|
def do_dt(self, attrs):
|
||||||
|
self.formatter.end_paragraph(1)
|
||||||
|
self.ddpop()
|
||||||
|
|
||||||
|
def handle_image(self, src, alt, ismap, align, width, height):
|
||||||
|
self.formatter.writer.viewer.showImage(src, alt, ismap, align, width, height)
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
@ -44,13 +198,397 @@ from tkwidget import MfxDialog
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
class tkHTMLViewer:
|
class tkHTMLViewer:
|
||||||
symbols_fn = {}
|
symbols_fn = {} # filenames, loaded in Application.loadImages3
|
||||||
|
symbols_img = {}
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, app=None, home=None):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.parent.wm_deiconify()
|
self.app = app
|
||||||
|
self.home = home
|
||||||
|
self.url = None
|
||||||
|
self.history = Struct(
|
||||||
|
list = [],
|
||||||
|
index = 0,
|
||||||
|
)
|
||||||
|
self.visited_urls = []
|
||||||
|
self.images = {}
|
||||||
|
self.anchor_tags = {}
|
||||||
|
|
||||||
def display(self, url, add=1, relpath=1):
|
# create buttons
|
||||||
pass
|
button_width = 8
|
||||||
|
vbox = gtk.VBox()
|
||||||
|
parent.table.attach(vbox,
|
||||||
|
0, 1, 0, 1,
|
||||||
|
gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL | gtk.SHRINK,
|
||||||
|
0, 0)
|
||||||
|
|
||||||
|
buttons_box = gtk.HBox()
|
||||||
|
vbox.pack_start(buttons_box, fill=True, expand=False)
|
||||||
|
for name, label, callback in (
|
||||||
|
('homeButton', _('Index'), self.goHome),
|
||||||
|
('backButton', _('Back'), self.goBack),
|
||||||
|
('forwardButton', _('Forward'), self.goForward),
|
||||||
|
('closeButton', _('Close'), self.destroy) ):
|
||||||
|
button = gtk.Button(label)
|
||||||
|
button.show()
|
||||||
|
button.connect('clicked', callback)
|
||||||
|
buttons_box.pack_start(button, fill=True, expand=False)
|
||||||
|
button.set_property('can-focus', False)
|
||||||
|
setattr(self, name, button)
|
||||||
|
|
||||||
|
# create text widget
|
||||||
|
self.textview = gtk.TextView()
|
||||||
|
self.textview.show()
|
||||||
|
self.textview.set_left_margin(10)
|
||||||
|
self.textview.set_right_margin(10)
|
||||||
|
self.textview.set_cursor_visible(False)
|
||||||
|
self.textview.set_editable(False)
|
||||||
|
self.textview.set_wrap_mode(gtk.WRAP_WORD)
|
||||||
|
self.textbuffer = self.textview.get_buffer()
|
||||||
|
|
||||||
|
sw = gtk.ScrolledWindow()
|
||||||
|
sw.set_property('hscrollbar-policy', gtk.POLICY_AUTOMATIC)
|
||||||
|
sw.set_property('vscrollbar-policy', gtk.POLICY_AUTOMATIC)
|
||||||
|
sw.set_property('border-width', 0)
|
||||||
|
sw.add(self.textview)
|
||||||
|
sw.show()
|
||||||
|
vbox.pack_start(sw, fill=True, expand=True)
|
||||||
|
self.vadjustment = sw.get_vadjustment()
|
||||||
|
self.hadjustment = sw.get_hadjustment()
|
||||||
|
|
||||||
|
# statusbar
|
||||||
|
self.statusbar = gtk.Statusbar()
|
||||||
|
self.statusbar.show()
|
||||||
|
vbox.pack_start(self.statusbar, fill=True, expand=False)
|
||||||
|
|
||||||
|
# load images
|
||||||
|
for name, fn in self.symbols_fn.items():
|
||||||
|
self.symbols_img[name] = self.getImage(fn)
|
||||||
|
|
||||||
|
# bindings
|
||||||
|
parent.connect('key-press-event', self.key_press_event)
|
||||||
|
parent.connect('destroy', self.destroy)
|
||||||
|
self.textview.connect('motion-notify-event', self.motion_notify_event)
|
||||||
|
self.textview.connect('leave-notify-event', self.leave_event)
|
||||||
|
self.textview.connect('enter-notify-event', self.motion_notify_event)
|
||||||
|
|
||||||
|
self._changed_cursor = False
|
||||||
|
|
||||||
|
self.createFontMap()
|
||||||
|
|
||||||
|
# cursor
|
||||||
|
self.defcursor = gdk.XTERM
|
||||||
|
self.handcursor = gdk.HAND2
|
||||||
|
##self.textview.realize()
|
||||||
|
##window = self.textview.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
|
##window.set_cursor(gdk.Cursor(self.defcursor))
|
||||||
|
|
||||||
|
parent.set_default_size(600, 440)
|
||||||
|
parent.show_all()
|
||||||
|
|
||||||
|
|
||||||
|
def motion_notify_event(self, widget, event):
|
||||||
|
x, y, _ = widget.window.get_pointer()
|
||||||
|
x, y = widget.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT, x, y)
|
||||||
|
tags = widget.get_iter_at_location(x, y).get_tags()
|
||||||
|
is_over_anchor = False
|
||||||
|
for tag, href in self.anchor_tags.values():
|
||||||
|
if tag in tags:
|
||||||
|
is_over_anchor = True
|
||||||
|
break
|
||||||
|
if is_over_anchor:
|
||||||
|
if not self._changed_cursor:
|
||||||
|
##print 'set cursor hand'
|
||||||
|
window = widget.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
|
window.set_cursor(gdk.Cursor(self.handcursor))
|
||||||
|
self._changed_cursor = True
|
||||||
|
self.statusbar.pop(0)
|
||||||
|
href = url = self.normurl(href)
|
||||||
|
self.statusbar.push(0, href)
|
||||||
|
else:
|
||||||
|
if self._changed_cursor:
|
||||||
|
##print 'set cursor xterm'
|
||||||
|
window = widget.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
|
window.set_cursor(gdk.Cursor(self.defcursor))
|
||||||
|
self._changed_cursor = False
|
||||||
|
self.statusbar.pop(0)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def leave_event(self, widget, event):
|
||||||
|
if self._changed_cursor:
|
||||||
|
##print 'set cursor xterm'
|
||||||
|
window = widget.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
|
window.set_cursor(gdk.Cursor(self.defcursor))
|
||||||
|
self._changed_cursor = False
|
||||||
|
self.statusbar.pop(0)
|
||||||
|
|
||||||
|
def anchor_event(self, tag, textview, event, iter, href):
|
||||||
|
#print 'anchor_event:', args
|
||||||
|
if event.type == gdk.BUTTON_PRESS and event.button == 1:
|
||||||
|
self.updateHistoryXYView()
|
||||||
|
self.display(href)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def key_press_event(self, w, e):
|
||||||
|
if gdk.keyval_name(e.keyval) == 'Escape':
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
def createFontMap(self):
|
||||||
|
try: ## if app
|
||||||
|
default_font = self.app.getFont('sans')
|
||||||
|
fixed_font = self.app.getFont('fixed')
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
default_font = ('times new roman', 12)
|
||||||
|
fixed_font = ('courier', 12)
|
||||||
|
size = default_font[1]
|
||||||
|
sign = 1
|
||||||
|
if size < 0: sign = -1
|
||||||
|
self.fontmap = {
|
||||||
|
'h1' : (default_font[0], size + 12*sign, 'bold'),
|
||||||
|
'h2' : (default_font[0], size + 8*sign, 'bold'),
|
||||||
|
'h3' : (default_font[0], size + 6*sign, 'bold'),
|
||||||
|
'h4' : (default_font[0], size + 4*sign, 'bold'),
|
||||||
|
'h5' : (default_font[0], size + 2*sign, 'bold'),
|
||||||
|
'h6' : (default_font[0], size + 1*sign, 'bold'),
|
||||||
|
'bold' : (default_font[0], size, 'bold'),
|
||||||
|
}
|
||||||
|
|
||||||
|
for tag_name in self.fontmap.keys():
|
||||||
|
font = self.fontmap[tag_name]
|
||||||
|
font = font[0]+' '+str(font[1])
|
||||||
|
tag = self.textbuffer.create_tag(tag_name, font=font)
|
||||||
|
tag.set_property('weight', pango.WEIGHT_BOLD)
|
||||||
|
|
||||||
|
font = font[0]+' '+str(font[1])
|
||||||
|
tag = self.textbuffer.create_tag('italic', style=pango.STYLE_ITALIC)
|
||||||
|
self.fontmap['italic'] = (font[0], size, 'italic')
|
||||||
|
font = fixed_font[0]+' '+str(fixed_font[1])
|
||||||
|
self.textbuffer.create_tag('pre', font=font)
|
||||||
|
self.fontmap['pre'] = fixed_font
|
||||||
|
# set default font
|
||||||
|
fd = pango.FontDescription(default_font[0]+' '+str(default_font[1]))
|
||||||
|
if 'bold' in default_font:
|
||||||
|
fd.set_weight(pango.WEIGHT_BOLD)
|
||||||
|
if 'italic' in default_font:
|
||||||
|
fd.set_style(pango.STYLE_ITALIC)
|
||||||
|
self.textview.modify_font(fd)
|
||||||
|
|
||||||
|
def destroy(self, *event):
|
||||||
|
self.parent.destroy()
|
||||||
|
self.parent = None
|
||||||
|
|
||||||
|
def get_position(self):
|
||||||
|
pos = self.hadjustment.get_value(), self.vadjustment.get_value()
|
||||||
|
return pos
|
||||||
|
|
||||||
|
def set_position(self, pos):
|
||||||
|
def callback(pos, hadj, vadj):
|
||||||
|
hadj.set_value(pos[0])
|
||||||
|
vadj.set_value(pos[1])
|
||||||
|
gobject.idle_add(callback, pos, self.hadjustment, self.vadjustment)
|
||||||
|
|
||||||
|
# locate a file relative to the current self.url
|
||||||
|
def basejoin(self, url, baseurl=None, relpath=1):
|
||||||
|
if baseurl is None:
|
||||||
|
baseurl = self.url
|
||||||
|
if 0:
|
||||||
|
import urllib
|
||||||
|
url = urllib.pathname2url(url)
|
||||||
|
if relpath and self.url:
|
||||||
|
url = urllib.basejoin(baseurl, url)
|
||||||
|
else:
|
||||||
|
url = os.path.normpath(url)
|
||||||
|
if relpath and baseurl and not os.path.isabs(url):
|
||||||
|
h1, t1 = os.path.split(url)
|
||||||
|
h2, t2 = os.path.split(baseurl)
|
||||||
|
if h1 != h2:
|
||||||
|
url = os.path.join(h2, h1, t1)
|
||||||
|
url = os.path.normpath(url)
|
||||||
|
return url
|
||||||
|
|
||||||
|
def normurl(self, url, with_protocol=True):
|
||||||
|
for p in REMOTE_PROTOCOLS:
|
||||||
|
if url.startswith(p):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
url = self.basejoin(url)
|
||||||
|
if with_protocol:
|
||||||
|
if os.name == 'nt':
|
||||||
|
url = url.replace('\\', '/')
|
||||||
|
url = 'file://'+url
|
||||||
|
return url
|
||||||
|
|
||||||
|
def openfile(self, url):
|
||||||
|
if url[-1:] == '/' or os.path.isdir(url):
|
||||||
|
url = os.path.join(url, 'index.html')
|
||||||
|
url = os.path.normpath(url)
|
||||||
|
return open(url, 'rb'), url
|
||||||
|
|
||||||
|
def display(self, url, add=1, relpath=1, position=(0,0)):
|
||||||
|
##print 'display:', url, position
|
||||||
|
# for some reason we have to stop the PySol demo
|
||||||
|
# (is this a multithread problem with Tkinter ?)
|
||||||
|
try:
|
||||||
|
##self.app.game.stopDemo()
|
||||||
|
##self.app.game._cancelDrag()
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ftp: and http: would work if we use urllib, but this widget is
|
||||||
|
# far too limited to display anything but our documentation...
|
||||||
|
for p in REMOTE_PROTOCOLS:
|
||||||
|
if url.startswith(p):
|
||||||
|
if not openURL(url):
|
||||||
|
self.errorDialog(PACKAGE + _('''HTML limitation:
|
||||||
|
The %s protocol is not supported yet.
|
||||||
|
|
||||||
|
Please use your standard web browser
|
||||||
|
to open the following URL:
|
||||||
|
%s
|
||||||
|
''') % (p, url))
|
||||||
|
return
|
||||||
|
|
||||||
|
# locate the file relative to the current url
|
||||||
|
url = self.basejoin(url, relpath=relpath)
|
||||||
|
|
||||||
|
# read the file
|
||||||
|
try:
|
||||||
|
file = None
|
||||||
|
if 0:
|
||||||
|
import urllib
|
||||||
|
file = urllib.urlopen(url)
|
||||||
|
else:
|
||||||
|
file, url = self.openfile(url)
|
||||||
|
data = file.read()
|
||||||
|
file.close()
|
||||||
|
file = None
|
||||||
|
except Exception, ex:
|
||||||
|
if file: file.close()
|
||||||
|
self.errorDialog(_('Unable to service request:\n') + url + '\n\n' + str(ex))
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
if file: file.close()
|
||||||
|
self.errorDialog(_('Unable to service request:\n') + url)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.url = url
|
||||||
|
if self.home is None:
|
||||||
|
self.home = self.url
|
||||||
|
if add:
|
||||||
|
self.addHistory(self.url, position=position)
|
||||||
|
|
||||||
|
##print self.history.index, self.history.list
|
||||||
|
if self.history.index > 1:
|
||||||
|
self.backButton.set_sensitive(True)
|
||||||
|
else:
|
||||||
|
self.backButton.set_sensitive(False)
|
||||||
|
if self.history.index < len(self.history.list):
|
||||||
|
self.forwardButton.set_sensitive(True)
|
||||||
|
else:
|
||||||
|
self.forwardButton.set_sensitive(False)
|
||||||
|
|
||||||
|
start, end = self.textbuffer.get_bounds()
|
||||||
|
self.textbuffer.delete(start, end)
|
||||||
|
|
||||||
|
writer = tkHTMLWriter(self.textbuffer, self, self.app)
|
||||||
|
fmt = formatter.AbstractFormatter(writer)
|
||||||
|
parser = tkHTMLParser(fmt)
|
||||||
|
parser.feed(data)
|
||||||
|
parser.close()
|
||||||
|
|
||||||
|
self.set_position(position)
|
||||||
|
|
||||||
|
self.parent.set_title(parser.title)
|
||||||
|
|
||||||
|
|
||||||
|
def addHistory(self, url, position=(0,0)):
|
||||||
|
if not url in self.visited_urls:
|
||||||
|
self.visited_urls.append(url)
|
||||||
|
if self.history.index > 0:
|
||||||
|
u, pos = self.history.list[self.history.index-1]
|
||||||
|
if u == url:
|
||||||
|
self.updateHistoryXYView()
|
||||||
|
return
|
||||||
|
del self.history.list[self.history.index : ]
|
||||||
|
self.history.list.append((url, position))
|
||||||
|
self.history.index = self.history.index + 1
|
||||||
|
|
||||||
|
def updateHistoryXYView(self):
|
||||||
|
if self.history.index > 0:
|
||||||
|
url, position = self.history.list[self.history.index-1]
|
||||||
|
position = self.get_position()
|
||||||
|
self.history.list[self.history.index-1] = (url, position)
|
||||||
|
|
||||||
|
def goBack(self, *event):
|
||||||
|
if self.history.index > 1:
|
||||||
|
self.updateHistoryXYView()
|
||||||
|
self.history.index = self.history.index - 1
|
||||||
|
url, position = self.history.list[self.history.index-1]
|
||||||
|
self.display(url, add=0, relpath=0, position=position)
|
||||||
|
|
||||||
|
def goForward(self, *event):
|
||||||
|
if self.history.index < len(self.history.list):
|
||||||
|
self.updateHistoryXYView()
|
||||||
|
url, position = self.history.list[self.history.index]
|
||||||
|
self.history.index = self.history.index + 1
|
||||||
|
self.display(url, add=0, relpath=0, position=position)
|
||||||
|
|
||||||
|
def goHome(self, *event):
|
||||||
|
if self.home and self.home != self.url:
|
||||||
|
self.updateHistoryXYView()
|
||||||
|
self.display(self.home, relpath=0)
|
||||||
|
|
||||||
|
def errorDialog(self, msg):
|
||||||
|
d = MfxMessageDialog(self.parent, title=PACKAGE+' HTML Problem',
|
||||||
|
text=msg, bitmap='warning',
|
||||||
|
strings=(_('&OK'),), default=0)
|
||||||
|
|
||||||
|
def getImage(self, fn):
|
||||||
|
if self.images.has_key(fn):
|
||||||
|
return self.images[fn]
|
||||||
|
try:
|
||||||
|
img = gdk.pixbuf_new_from_file(fn)
|
||||||
|
except:
|
||||||
|
img = None
|
||||||
|
self.images[fn] = img
|
||||||
|
return img
|
||||||
|
|
||||||
|
def showImage(self, src, alt, ismap, align, width, height):
|
||||||
|
url = self.basejoin(src)
|
||||||
|
img = self.getImage(url)
|
||||||
|
if img:
|
||||||
|
iter = self.textbuffer.get_end_iter()
|
||||||
|
self.textbuffer.insert_pixbuf(iter, img)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# //
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
def tkhtml_main(args):
|
||||||
|
try:
|
||||||
|
url = args[1]
|
||||||
|
except:
|
||||||
|
url = os.path.join(os.pardir, os.pardir, 'data', 'html', 'index.html')
|
||||||
|
top = gtk.Window()
|
||||||
|
table = gtk.Table()
|
||||||
|
table.show()
|
||||||
|
top.add(table)
|
||||||
|
top.table = table
|
||||||
|
viewer = tkHTMLViewer(top)
|
||||||
|
viewer.app = None
|
||||||
|
viewer.display(url)
|
||||||
|
top.connect('destroy', lambda w: gtk.main_quit())
|
||||||
|
gtk.main()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(tkhtml_main(sys.argv))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ class _MyDialog(gtk.Dialog):
|
||||||
self.__dict__[name] = value
|
self.__dict__[name] = value
|
||||||
|
|
||||||
def quit(self, *args):
|
def quit(self, *args):
|
||||||
|
self.status = 0
|
||||||
self.hide()
|
self.hide()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
@ -88,7 +89,6 @@ class MfxDialog(_MyDialog):
|
||||||
if modal:
|
if modal:
|
||||||
setTransient(self, parent)
|
setTransient(self, parent)
|
||||||
|
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
if width > 0 or height > 0:
|
if width > 0 or height > 0:
|
||||||
self.set_size_request(width, height)
|
self.set_size_request(width, height)
|
||||||
|
@ -96,14 +96,22 @@ class MfxDialog(_MyDialog):
|
||||||
self.set_title(title)
|
self.set_title(title)
|
||||||
#
|
#
|
||||||
self.connect('key-press-event', self._keyPressEvent)
|
self.connect('key-press-event', self._keyPressEvent)
|
||||||
self.show()
|
|
||||||
|
|
||||||
def createBox(self):
|
|
||||||
hbox = gtk.HBox(spacing=5)
|
def createBox(self, widget_class=gtk.HBox):
|
||||||
hbox.set_border_width(5)
|
box = widget_class(spacing=5)
|
||||||
self.vbox.pack_start(hbox)
|
box.set_border_width(5)
|
||||||
hbox.show()
|
self.vbox.pack_start(box)
|
||||||
return hbox, self.action_area
|
box.show()
|
||||||
|
return box, self.action_area
|
||||||
|
|
||||||
|
createHBox = createBox
|
||||||
|
|
||||||
|
def createVBox(self):
|
||||||
|
return self.createBox(widget_class=gtk.VBox)
|
||||||
|
|
||||||
|
def createTable(self):
|
||||||
|
return self.createBox(widget_class=gtk.Table)
|
||||||
|
|
||||||
def createBitmaps(self, box, kw):
|
def createBitmaps(self, box, kw):
|
||||||
if kw['bitmap']:
|
if kw['bitmap']:
|
||||||
|
@ -133,10 +141,10 @@ class MfxDialog(_MyDialog):
|
||||||
continue
|
continue
|
||||||
text = text.replace('&', '_')
|
text = text.replace('&', '_')
|
||||||
b = gtk.Button(text)
|
b = gtk.Button(text)
|
||||||
b.set_flags(gtk.CAN_DEFAULT)
|
b.set_property('can-default', True)
|
||||||
if i == default:
|
if i == default:
|
||||||
b.grab_focus()
|
b.grab_focus()
|
||||||
##~ b.grab_default()
|
#b.grab_default()
|
||||||
b.set_data("user_data", i)
|
b.set_data("user_data", i)
|
||||||
b.connect("clicked", self.done)
|
b.connect("clicked", self.done)
|
||||||
box.pack_start(b)
|
box.pack_start(b)
|
||||||
|
@ -181,17 +189,22 @@ class MfxMessageDialog(MfxDialog):
|
||||||
|
|
||||||
label = gtk.Label(kw['text'])
|
label = gtk.Label(kw['text'])
|
||||||
label.set_justify(gtk.JUSTIFY_CENTER)
|
label.set_justify(gtk.JUSTIFY_CENTER)
|
||||||
label.xpad, label.ypad = kw['padx'], kw['pady']
|
label.set_property('xpad', kw['padx'])
|
||||||
|
label.set_property('ypad', kw['pady'])
|
||||||
top_box.pack_start(label)
|
top_box.pack_start(label)
|
||||||
|
|
||||||
self.createButtons(bottom_box, kw)
|
self.createButtons(bottom_box, kw)
|
||||||
|
|
||||||
label.show()
|
label.show()
|
||||||
|
self.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||||
|
##self.set_position(gtk.WIN_POS_CENTER)
|
||||||
|
|
||||||
|
self.show_all()
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
|
||||||
def initKw(self, kw):
|
def initKw(self, kw):
|
||||||
if kw.has_key('bitmap'):
|
#if kw.has_key('bitmap'):
|
||||||
kwdefault(kw, width=250, height=150)
|
# kwdefault(kw, width=250, height=150)
|
||||||
return MfxDialog.initKw(self, kw)
|
return MfxDialog.initKw(self, kw)
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,13 +273,13 @@ class MfxSimpleEntry(_MyDialog):
|
||||||
self.entry.grab_focus()
|
self.entry.grab_focus()
|
||||||
button = gtk.Button("OK")
|
button = gtk.Button("OK")
|
||||||
button.connect("clicked", self.done)
|
button.connect("clicked", self.done)
|
||||||
button.set_flags(CAN_DEFAULT)
|
button.set_flags(gtk.CAN_DEFAULT)
|
||||||
self.action_area.pack_start(button)
|
self.action_area.pack_start(button)
|
||||||
button.show()
|
button.show()
|
||||||
button.grab_default()
|
button.grab_default()
|
||||||
button = gtk.Button("Cancel")
|
button = gtk.Button("Cancel")
|
||||||
button.connect("clicked", self.quit)
|
button.connect("clicked", self.quit)
|
||||||
button.set_flags(CAN_DEFAULT)
|
button.set_flags(gtk.CAN_DEFAULT)
|
||||||
self.action_area.pack_start(button)
|
self.action_area.pack_start(button)
|
||||||
button.show()
|
button.show()
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ class _MfxToplevel(gtk.Window):
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL)
|
gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL)
|
||||||
##~ self.style = self.get_style().copy()
|
##~ self.style = self.get_style().copy()
|
||||||
self.set_style(self.style)
|
##~ self.set_style(self.style)
|
||||||
#self.vbox = gtk.VBox()
|
#self.vbox = gtk.VBox()
|
||||||
#self.vbox.show()
|
#self.vbox.show()
|
||||||
#self.add(self.vbox)
|
#self.add(self.vbox)
|
||||||
|
@ -145,7 +145,7 @@ class _MfxToplevel(gtk.Window):
|
||||||
print "Toplevel configure:", k, v
|
print "Toplevel configure:", k, v
|
||||||
raise AttributeError, k
|
raise AttributeError, k
|
||||||
if height > 0 and width > 0:
|
if height > 0 and width > 0:
|
||||||
print 'configure: size:', width, height
|
##print 'configure: size:', width, height
|
||||||
## FIXME
|
## FIXME
|
||||||
#self.set_default_size(width, height)
|
#self.set_default_size(width, height)
|
||||||
#self.set_size_request(width, height)
|
#self.set_size_request(width, height)
|
||||||
|
@ -202,12 +202,15 @@ class _MfxToplevel(gtk.Window):
|
||||||
|
|
||||||
def wm_geometry(self, newGeometry=None):
|
def wm_geometry(self, newGeometry=None):
|
||||||
##print 'wm_geometry', newGeometry
|
##print 'wm_geometry', newGeometry
|
||||||
if newGeometry == '':
|
print 'allow_shrink:', self.allow_shrink
|
||||||
self.reshow_with_initial_size()
|
if not newGeometry:
|
||||||
|
pass
|
||||||
|
##self.reshow_with_initial_size()
|
||||||
##self.resize(1, 1)
|
##self.resize(1, 1)
|
||||||
else:
|
else:
|
||||||
w, h = newGeometry
|
pass
|
||||||
self.resize(w, h)
|
##w, h = newGeometry
|
||||||
|
##self.resize(w, h)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,7 +230,8 @@ class _MfxToplevel(gtk.Window):
|
||||||
##~ self.set_icon_name(name)
|
##~ self.set_icon_name(name)
|
||||||
|
|
||||||
def wm_minsize(self, width, height):
|
def wm_minsize(self, width, height):
|
||||||
self.set_geometry_hints(min_width=width, min_height=height)
|
pass
|
||||||
|
##~ self.set_geometry_hints(min_width=width, min_height=height)
|
||||||
|
|
||||||
def wm_protocol(self, name=None, func=None):
|
def wm_protocol(self, name=None, func=None):
|
||||||
if name == 'WM_DELETE_WINDOW':
|
if name == 'WM_DELETE_WINDOW':
|
||||||
|
|
|
@ -57,31 +57,31 @@ class PysolToolbar(PysolToolbarActions):
|
||||||
self.toolbar = gtk.Toolbar(gtk.ORIENTATION_HORIZONTAL,
|
self.toolbar = gtk.Toolbar(gtk.ORIENTATION_HORIZONTAL,
|
||||||
gtk.TOOLBAR_ICONS)
|
gtk.TOOLBAR_ICONS)
|
||||||
|
|
||||||
#self.bg = top.get_style().bg[gtk.STATE_NORMAL]
|
|
||||||
ui_info = '''
|
ui_info = '''
|
||||||
<ui>
|
<ui>
|
||||||
<toolbar name='ToolBar'>
|
<toolbar name='toolbar'>
|
||||||
<toolitem action='New'/>
|
<toolitem action='new'/>
|
||||||
<toolitem action='Restart'/>
|
<toolitem action='restart'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<toolitem action='Open'/>
|
<toolitem action='open'/>
|
||||||
<toolitem action='Save'/>
|
<toolitem action='save'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<toolitem action='Undo'/>
|
<toolitem action='undo'/>
|
||||||
<toolitem action='Redo'/>
|
<toolitem action='redo'/>
|
||||||
<toolitem action='Autodrop'/>
|
<toolitem action='autodrop'/>
|
||||||
|
<toolitem action='pause'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<toolitem action='Stats'/>
|
<toolitem action='stats'/>
|
||||||
<toolitem action='Rules'/>
|
<toolitem action='rules'/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<toolitem action='Quit'/>
|
<toolitem action='quit'/>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
</ui>
|
</ui>
|
||||||
'''
|
'''
|
||||||
ui_manager = self.top.ui_manager # created in menubar.py
|
ui_manager = self.top.ui_manager # created in menubar.py
|
||||||
ui_manager_id = ui_manager.add_ui_from_string(ui_info)
|
ui_manager_id = ui_manager.add_ui_from_string(ui_info)
|
||||||
|
|
||||||
toolbar = ui_manager.get_widget("/ToolBar")
|
toolbar = ui_manager.get_widget("/toolbar")
|
||||||
toolbar.set_tooltips(True)
|
toolbar.set_tooltips(True)
|
||||||
toolbar.set_style(gtk.TOOLBAR_ICONS)
|
toolbar.set_style(gtk.TOOLBAR_ICONS)
|
||||||
toolbar.show()
|
toolbar.show()
|
||||||
|
@ -93,36 +93,6 @@ class PysolToolbar(PysolToolbarActions):
|
||||||
toolbar.show()
|
toolbar.show()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# no longer needed
|
|
||||||
self.bg = None
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# util
|
|
||||||
def _createButton(self, name, command, padx=0, stock=None, tooltip=None):
|
|
||||||
##button = self.toolbar.append_item(name, tooltip, "", stock, command)
|
|
||||||
##button = self.toolbar.insert_stock(stock, tooltip, '', command, None, -1)
|
|
||||||
image = gtk.Image()
|
|
||||||
image.set_from_stock(stock, gtk.ICON_SIZE_SMALL_TOOLBAR)
|
|
||||||
|
|
||||||
button = gtk.ToolButton(None, name)
|
|
||||||
button.set_tooltip(tooltip)
|
|
||||||
#button.set_relief(gtk.RELIEF_NONE)
|
|
||||||
#button.connect('activate', command)
|
|
||||||
self.toolbar.insert(button, -1)
|
|
||||||
setattr(self, name + "_button", button)
|
|
||||||
|
|
||||||
|
|
||||||
def _createLabel(self, name, padx=0, side='IGNORE', tooltip=None):
|
|
||||||
## FIXME: append_widget
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _createSeparator(self):
|
|
||||||
self.toolbar.append_space()
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# wrappers
|
# wrappers
|
||||||
#
|
#
|
||||||
|
|
|
@ -300,7 +300,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
menu.add_command(label=n_("&Clear bookmarks"), command=self.mClearBookmarks)
|
menu.add_command(label=n_("&Clear bookmarks"), command=self.mClearBookmarks)
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
|
|
||||||
menu.add_command(label=n_("Restart &game"), command=self.mRestart, accelerator=m+"G")
|
menu.add_command(label=n_("Restart"), command=self.mRestart, accelerator=m+"G")
|
||||||
|
|
||||||
menu = MfxMenu(self.__menubar, label=n_("&Game"))
|
menu = MfxMenu(self.__menubar, label=n_("&Game"))
|
||||||
menu.add_command(label=n_("&Deal cards"), command=self.mDeal, accelerator="D")
|
menu.add_command(label=n_("&Deal cards"), command=self.mDeal, accelerator="D")
|
||||||
|
|
|
@ -232,9 +232,10 @@ class tkHTMLViewer:
|
||||||
symbols_fn = {} # filenames, loaded in Application.loadImages3
|
symbols_fn = {} # filenames, loaded in Application.loadImages3
|
||||||
symbols_img = {}
|
symbols_img = {}
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, app=None, home=None):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.home = None
|
self.app = app
|
||||||
|
self.home = home
|
||||||
self.url = None
|
self.url = None
|
||||||
self.history = Struct(
|
self.history = Struct(
|
||||||
list = [],
|
list = [],
|
||||||
|
@ -371,11 +372,10 @@ class tkHTMLViewer:
|
||||||
def display(self, url, add=1, relpath=1, xview=0, yview=0):
|
def display(self, url, add=1, relpath=1, xview=0, yview=0):
|
||||||
# for some reason we have to stop the PySol demo
|
# for some reason we have to stop the PySol demo
|
||||||
# (is this a multithread problem with Tkinter ?)
|
# (is this a multithread problem with Tkinter ?)
|
||||||
if self.__dict__.get("app"):
|
if self.app and self.app.game:
|
||||||
if self.app and self.app.game:
|
self.app.game.stopDemo()
|
||||||
self.app.game.stopDemo()
|
##self.app.game._cancelDrag()
|
||||||
##self.app.game._cancelDrag()
|
##pass
|
||||||
##pass
|
|
||||||
|
|
||||||
# ftp: and http: would work if we use urllib, but this widget is
|
# ftp: and http: would work if we use urllib, but this widget is
|
||||||
# far too limited to display anything but our documentation...
|
# far too limited to display anything but our documentation...
|
||||||
|
|
Loading…
Add table
Reference in a new issue