diff --git a/add_card_dialog.py b/add_card_dialog.py new file mode 100644 index 0000000..349def6 --- /dev/null +++ b/add_card_dialog.py @@ -0,0 +1,98 @@ +import os + +from PyQt5 import uic +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog , QListWidgetItem + +import asl_cards.db as db +from constants import * +import globals + +# --------------------------------------------------------------------- + +class AddCardDialog( QDialog ) : + """Allow the user to select an ASL card, based on nationality & card type.""" + + def __init__( self , parent ) : + # initialize + self.selected_card = None + super(AddCardDialog,self).__init__( parent=parent ) + # initialize the dialog + uic.loadUi( os.path.join(globals.base_dir,"ui/add_card_dialog.ui") , self ) + self.setMinimumSize( self.size() ) + self.lb_cards.setSortingEnabled( True ) + w = self.buttons_widget + self.xmargin = w.x() + self.ymargin = self.size().height() - (w.y() + w.height()) + # load the dialog + for nationality in globals.cards : + self.cbo_nationality.addItem( nationality ) + # connect our handlers + self.cbo_nationality.currentIndexChanged[str].connect( self.on_nationality_changed ) + self.ok_button.clicked.connect( self.on_ok ) + for rb in [self.rb_vehicles,self.rb_ordnance] : + rb.clicked.connect( self.on_card_type_changed ) + # select the initial nationality (this will load the rest of the dialog) + self.cbo_nationality.setCurrentIndex( 0 ) + self.on_nationality_changed( self.cbo_nationality.itemText(0) ) + + def on_ok( self ) : + # accept the currently selected card + item = self.lb_cards.currentItem() + self.selected_card = item.data(Qt.UserRole) if item else None + self.accept() + + def on_nationality_changed( self , val ) : + """Update the dialog when the active nationality is changed.""" + # reload the available cards for the selected nationality + cards = globals.cards[ val ] + self.lb_cards.clear() + # update the vehicle/ordnance radio boxes + if self.rb_vehicles.isChecked() : + curr_rb = self.rb_vehicles + elif self.rb_ordnance.isChecked() : + curr_rb = self.rb_ordnance + else : + curr_rb = None + self.rb_vehicles.setEnabled( db.TAGTYPE_VEHICLE in cards ) + self.rb_ordnance.setEnabled( db.TAGTYPE_ORDNANCE in cards ) + if curr_rb is None or not curr_rb.isEnabled() : + for rb in [self.rb_vehicles,self.rb_ordnance] : + if rb.isEnabled() : + rb.setChecked( True ) + break + # reload the cards + self.on_card_type_changed() + + def on_card_type_changed( self ) : + """Update the dialog when the active card type is changed.""" + self.lb_cards.clear() + # figure out what type of cards to show + if self.rb_vehicles.isChecked() : + card_type = db.TAGTYPE_VEHICLE + elif self.rb_ordnance.isChecked() : + card_type = db.TAGTYPE_ORDNANCE + else : + return + # reload the available cards + cards = globals.cards[ self.cbo_nationality.currentText() ] + cards = cards.get( card_type ) + if cards is None : + assert False + return + for card in cards : + item = QListWidgetItem( card.name ) + item.setData( Qt.UserRole , card ) + self.lb_cards.addItem( item ) + self.lb_cards.setCurrentRow( 0 ) + self.lb_cards.setFocus() + + def resizeEvent( self , evt ) : + # handle the event + w = self.buttons_widget + self.buttons_widget.setGeometry( + self.xmargin , self.size().height() - self.ymargin - w.height() , + self.size().width() - 2*self.xmargin , w.height() + ) + w = self.lb_cards + w.resize( self.size().width() - 2*self.xmargin , self.buttons_widget.y() - w.y() ) diff --git a/asl_cards/__main__.py b/asl_cards/__main__.py index 3ace0be..b405ea3 100755 --- a/asl_cards/__main__.py +++ b/asl_cards/__main__.py @@ -40,6 +40,7 @@ def main( args ) : log_progress = True elif opt in ["-h","--help","-?"] : print_help() + sys.exit( 0 ) else : raise RuntimeError( "Unknown argument: {}".format( opt ) ) if not db_fname : raise RuntimeError( "No database was specified." ) diff --git a/asl_cards/db.py b/asl_cards/db.py index 7f1eb9c..cc48e1e 100644 --- a/asl_cards/db.py +++ b/asl_cards/db.py @@ -6,6 +6,10 @@ from sqlalchemy import Column , ForeignKey , String , Integer , Binary # --------------------------------------------------------------------- +# tag types +TAGTYPE_VEHICLE = "vehicle" +TAGTYPE_ORDNANCE = "ordnance" + db_engine = None db_session = None @@ -100,10 +104,10 @@ def load_cards() : for card in cards : d = card_index[ card.nationality ] tag = card.tag.lower() - if tag.startswith( "ordnance" ) : - tag_type = "ordnance" - elif tag.startswith( "vehicle" ) : - tag_type = "vehicle" + if tag.startswith( "vehicle" ) : + tag_type = TAGTYPE_VEHICLE + elif tag.startswith( "ordnance" ) : + tag_type = TAGTYPE_ORDNANCE else : raise RuntimeError( "Unknown tag type ({}) for AslCard: {}".format( tag , card ) ) d[ tag_type ].append( card ) diff --git a/globals.py b/globals.py index 7dffcd9..4c39302 100644 --- a/globals.py +++ b/globals.py @@ -7,4 +7,4 @@ app_settings = None debug_settings = None # AslCard table -card = {} # { nationality: { "ordnance|vehicle": [ AslCard's ] } } +card = {} # { nationality: { tag-type: [ AslCard's ] } } diff --git a/main_window.py b/main_window.py index 227fae1..b0a7dd5 100755 --- a/main_window.py +++ b/main_window.py @@ -3,16 +3,18 @@ import os from PyQt5.QtCore import Qt , QPoint , QSize from PyQt5.QtWidgets import QMainWindow , QVBoxLayout , QHBoxLayout , QWidget , QTabWidget , QLabel -from PyQt5.QtWidgets import QMessageBox +from PyQt5.QtWidgets import QDialog , QMessageBox , QAction from PyQt5.QtGui import QPainter , QPixmap , QIcon , QBrush import asl_cards.db as db from constants import * import globals +import add_card_dialog # --------------------------------------------------------------------- class AslCardWidget( QWidget ) : + """Simple widget that displays the image for an ASL Card.""" def __init__( self , card ) : # initialize @@ -45,20 +47,24 @@ class MainWindow( QMainWindow ) : # initialize the window self.setWindowTitle( APP_NAME ) self.setWindowIcon( QIcon("resources/app.ico") ) + # initialize the menu + menu_bar = self.menuBar() + file_menu = menu_bar.addMenu( "&File" ) + action = QAction( "&Add" , self ) + action.setShortcut( "Ctrl+A" ) + action.setStatusTip( "Add an ASL Card." ) + action.triggered.connect( self.on_add_card ) + file_menu.addAction( action ) + action = QAction( "E&xit" , self ) + action.setStatusTip( "Close the program." ) + action.triggered.connect( self.close ) + file_menu.addAction( action ) # 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) ) ) # initialize the window controls self.tab_widget = QTabWidget( self ) self.tab_widget.setTabsClosable( True ) - self.tab_widgets = [] - - for i in range(0,3) : # FIXME! - card = globals.cards["Chinese"]["ordnance"][ i ] - w = AslCardWidget( card ) - self.tab_widget.addTab( w , card.name ) - self.tab_widgets.append( w ) - self.setCentralWidget( self.tab_widget ) def closeEvent( self , evt ) : @@ -81,3 +87,16 @@ class MainWindow( QMainWindow ) : """Handle key-presses.""" if evt.key() == Qt.Key_Escape and globals.debug_settings.value("Debug/AllowEscapeToClose",type=bool) : self.close() + + def on_add_card( self ) : + dlg = add_card_dialog.AddCardDialog( self ) + rc = dlg.exec() + if rc == QDialog.Accepted : + # add a new tab for the selected card + card = dlg.selected_card + if not card : + assert False + return + w = AslCardWidget( card ) + index = self.tab_widget.addTab( w , card.name ) + self.tab_widget.setCurrentIndex( index ) diff --git a/ui/add_card_dialog.ui b/ui/add_card_dialog.ui new file mode 100644 index 0000000..7003d56 --- /dev/null +++ b/ui/add_card_dialog.ui @@ -0,0 +1,176 @@ + + + MyDialog + + + + 0 + 0 + 380 + 336 + + + + + + -1 + 9 + 301 + 55 + + + + + 0 + 0 + + + + + 16777215 + 55 + + + + + + 10 + 10 + 81 + 21 + + + + &Nationality: + + + cbo_nationality + + + + + + 170 + 30 + 91 + 26 + + + + &Ordnance + + + + + + 90 + 10 + 131 + 21 + + + + + + + 90 + 30 + 81 + 26 + + + + &Vehicles + + + + + + + 10 + 280 + 361 + 46 + + + + + 0 + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &OK + + + true + + + + + + + Cancel + + + + + + + + + 10 + 50 + 53 + 20 + + + + + 16777215 + 20 + + + + &Cards: + + + lb_cards + + + + + + 9 + 71 + 362 + 211 + + + + + 0 + 0 + + + + + + +