Allow keyboard accelerators to cycle through a nationality's cards.

master
Pacman Ghost 7 years ago
parent 16f9aca710
commit dfe63375de
  1. 28
      asl_cards/natinfo.py
  2. 10
      asl_cards/natinfo/natinfo.json
  3. 11
      asl_cards/tests/natinfo-data/natinfo.json
  4. 22
      asl_cards/tests/test_natinfo.py
  5. 40
      main_window.py

@ -10,12 +10,16 @@ _base_dir = None
# ---------------------------------------------------------------------
def _get_key( nat ) :
def _make_key( nat ) :
"""Get the JSON key for a nationality.
We require the JSON keys to be lower-case, with no spaces (not strictly necessary, but not a bad idea :-/).
"""
return nat.lower().replace( " " , "-" )
return nat.lower().replace( " " , "-" ) if nat else None
def display_name_from_key( key ) :
"""Get the nationality display string from a JSON key."""
return key.replace( "-" , " " ).capitalize()
# ---------------------------------------------------------------------
@ -35,16 +39,32 @@ def dump() :
for nat in sorted(_nat_info.keys()) :
print( "{}:".format( nat ) )
print( "- flag = {}".format( get_flag(nat) ) )
print( "- accel = {}".format( get_accel_for_nat(nat) ) )
def get_flag( nat ) :
"""Locate the flag image file for a nationality.
These are set in the JSON data file at $/{nat}/flag. If there is no entry, the default is $/flags/${nat}.png
"""
key = _get_key( nat )
key = _make_key( nat )
try :
fname = _nat_info[ key ][ "flag" ]
except ( KeyError , TypeError ) :
fname = key + ".png"
fname = "{}.png".format( key )
fname = os.path.join( _base_dir , os.path.join("flags", fname) )
return fname if os.path.isfile(fname) else None
def get_nats_for_accel( ch ) :
"""Get the nationalities for an accelerator key."""
if ch is None : return None
ch = ch.strip().lower()
if not ch : return None
return [ nat for nat,vals in _nat_info.items() if vals.get("accelerator","").lower() == ch ]
def get_accel_for_nat( nat ) :
"""Get the accelerator key for a nationality."""
key = _make_key( nat )
try :
return _nat_info[ key ][ "accelerator" ].lower()
except ( KeyError , TypeError ) :
return None

@ -4,6 +4,7 @@
} ,
"american": {
"accelerator": "U"
} ,
"axis-minor": {
@ -14,6 +15,7 @@
} ,
"british": {
"accelerator": "B"
} ,
"bulgarian": {
@ -21,6 +23,7 @@
} ,
"chinese": {
"accelerator": "C"
} ,
"croatian": {
@ -36,13 +39,16 @@
} ,
"finnish": {
"flag": "axis-minor.png"
"flag": "axis-minor.png" ,
"accelerator": "F"
} ,
"french": {
"accelerator": "F"
} ,
"german": {
"accelerator": "G"
} ,
"greek": {
@ -57,6 +63,7 @@
} ,
"japanese": {
"accelerator": "J"
} ,
"polish": {
@ -68,6 +75,7 @@
} ,
"russian": {
"accelerator": "R"
} ,
"slovakian": {

@ -1,6 +1,7 @@
{
"german": {
"_comment_": "this nationality has no flag"
"_comment_": "this nationality has no flag" ,
"accelerator": "g"
} ,
"russian": {
@ -8,7 +9,13 @@
} ,
"american" :{
"_comment_": "this nationality has a default flag"
"_comment_": "this nationality has a default flag" ,
"accelerator": "a"
} ,
"australian" :{
"_comment_": "this nationality has the same accelerator as the americans" ,
"accelerator": "A"
} ,
"japanese" :{

@ -21,10 +21,30 @@ class TestNatInfo( TestCaseBase ) :
def test_flags( self ) :
"""Test locating the flag image files for each nationality."""
self.assertIsNone( natinfo.get_flag( "xxx" ) )
self.assertIsNone( natinfo.get_flag( "german" ) )
self.assertTrue( natinfo.get_flag("american").endswith( "/flags/american.png" ) )
self.assertTrue( natinfo.get_flag("japanese").endswith( "/flags/japanese-flag.gif" ) )
self.assertIsNone( natinfo.get_flag( "_unknown_" ) )
self.assertIsNone( natinfo.get_flag( "" ) )
self.assertIsNone( natinfo.get_flag( None ) )
def test_accelerators( self ) :
"""Test nationality accelerators."""
# test getting the nationalities that use a given accelerator key
self.assertEqual( natinfo.get_nats_for_accel("G") , ["german"] )
self.assertEqual( natinfo.get_nats_for_accel("g") , ["german"] )
self.assertEqual( natinfo.get_nats_for_accel("a") , ["american","australian"] )
self.assertEqual( natinfo.get_nats_for_accel("russian") , [] )
self.assertEqual( natinfo.get_nats_for_accel("_") , [] )
self.assertIsNone( natinfo.get_nats_for_accel( "" ) )
self.assertIsNone( natinfo.get_nats_for_accel( None ) )
# test getting the accelerator key for a given nationality
self.assertEqual( natinfo.get_accel_for_nat("german") , "g" )
self.assertEqual( natinfo.get_accel_for_nat("american") , "a" )
self.assertEqual( natinfo.get_accel_for_nat("australian") , "a" )
self.assertIsNone( natinfo.get_accel_for_nat( "" ) )
self.assertIsNone( natinfo.get_accel_for_nat( None ) )
# ---------------------------------------------------------------------

@ -73,15 +73,51 @@ class MainWindow( QMainWindow ) :
action.setStatusTip( "Close the program." )
action.triggered.connect( self.close )
file_menu.addAction( action )
self.tab_widget = None
self._update_ui()
# initialize the menu
self.view_menu = menu_bar.addMenu( "&View" )
self.view_menu.aboutToShow.connect( self.on_about_to_show_view_menu )
# load the window settings
self.resize( globals.app_settings.value( MAINWINDOW_SIZE , QSize(500,300) ) )
self.move( globals.app_settings.value( MAINWINDOW_POSITION , QPoint(200,200) ) )
# show the startup form
self.tab_widget = None
self.setCentralWidget(
StartupWidget( db_fname , parent=self )
)
self._update_ui()
def on_about_to_show_view_menu( self ) :
# figure out what nationalities are currently open
nats = []
for i in range(0,self.tab_widget.count()) :
widget = self.tab_widget.widget( i )
if type(widget) is not AslCardWidget : continue
card = widget.card
if card.nationality not in nats :
nats.append( card.nationality )
# rebuild the View menu
def cycle( nat ) :
# cycle to the nationality's next card
index = start_index = self.tab_widget.currentIndex()
while True :
index = (index + 1) % self.tab_widget.count()
if index == start_index :
break
card = self.tab_widget.widget( index ).card
if card.nationality == nat :
self.tab_widget.setCurrentIndex( index )
break
self.view_menu.clear()
for nat in nats :
action = QAction( "Next {} card".format(nat) , self )
fname = natinfo.get_flag( nat )
if fname :
action.setIcon( QIcon(fname) )
accel = natinfo.get_accel_for_nat( nat )
if accel :
action.setShortcut( "Ctrl+{}".format( accel ) )
action.triggered.connect( lambda qthack,nat=nat: cycle(nat) )
self.view_menu.addAction( action )
def start_main_app( self , db_fname ) :
"""Start the main app."""

Loading…
Cancel
Save