def __init__( self, parent ): Qt.QWidget.__init__( self, parent ) # Actions # Actions.createGraphEditorActions( self ) # Menus # #menuBar = Qt.QMenuBar( self ) # #fileMenu = menuBar.addMenu( 'File' ) #viewMenu = menuBar.addMenu( 'View' ) # #fileMenu.addAction( Actions.graphEditor.loadDynamicNode ) #viewMenu.addAction( Actions.graphEditor.frameAll ) # Graph editor # graphEditor = Cellule.appli.createGraphEditor( Cellule.fromSIP( self ) ) graphEditorSIP = Cellule.toSIP( graphEditor, Qt.QWidget ) # Layout # layout = Qt.QVBoxLayout( self ) #layout.addWidget( menuBar ) layout.addWidget( graphEditorSIP )
def loadDynamicNode(): mainWinSIP = Cellule.toSIP( Cellule.appli.mainWin, Qt.QMainWindow ) fileName = Qt.QFileDialog.getOpenFileName( mainWinSIP, 'Load dynamic node', '', 'Dynamic nodes (*.cpp)' ) if not fileName.isEmpty(): Cellule.appli.scene.loadDynamicNode( Cellule.fromSIP( fileName ) )
def openScene(): mainWinSIP = Cellule.toSIP( Cellule.appli.mainWin, Qt.QMainWindow ) fileName = Qt.QFileDialog.getOpenFileName( mainWinSIP, 'Open Scene', '', 'Cellule scenes (*.cel)' ) if not fileName.isEmpty(): Cellule.appli.scene.load( Cellule.fromSIP( fileName ) )
def saveImageAs( view2D ): mainWinSIP = Cellule.toSIP( Cellule.appli.mainWin, Qt.QMainWindow ) fileName = Qt.QFileDialog.getSaveFileName( mainWinSIP, 'Save Rendered Image', '', 'Image files(*.png *.tiff *.bmp)' ) if not fileName.isEmpty(): view2D.renderArea.saveAs( Cellule.fromSIP( fileName ) )
def saveSceneAs(): mainWinSIP = Cellule.toSIP( Cellule.appli.mainWin, Qt.QMainWindow ) fileName = Qt.QFileDialog.getSaveFileName( mainWinSIP, 'Save Scene', '', 'Cellule scenes (*.cel)' ) if not fileName.isEmpty(): Cellule.appli.scene.saveAs( Cellule.fromSIP( fileName ) )
def setUp(self): # on crée la cellule qui sera testée self.cellule = Cellule(numero=1, attaque=0, defense=0, attaqueMax=10, defenseMax=30, production=3, couleurJoueur=2, x=100, y=100, rayon=50)
def initialiserGrille(self): """ Cette fonction remplie la grille de cellules mortes. Elle renvoie la grille une fois remplie """ grille = [] for ligne in range(NB_LIGNES): grille.append([]) for colonne in range(NB_COLONNES): if ligne * ( HAUTEUR_CELLULE + MARGE_CELLULE ) >= HAUTEUR_BARRE: # pour chaque cellule si elle est # en dessous de la barre d'options nouvelle_cellule = Cellule( ligne, colonne, 0) # On cree un nouvel objet de notre classe 'Cellule' grille[ligne].append( nouvelle_cellule) # On l'ajoute dans notre grille nouvelle_cellule.afficher(self.fenetre) # et on l'affiche return grille
def test_ajouterLien_pasCellule(self): cellule1 = Cellule(numero=0, attaque=0, defense=5, attaqueMax=25, defenseMax=30, production=2, couleurJoueur=8, x=10, y=60, rayon=45) cellule2 = Cellule(numero=2, attaque=10, defense=8, attaqueMax=20, defenseMax=36, production=4, couleurJoueur=0, x=10, y=60, rayon=40) lien = Lien(cellule1, cellule2, 99) self.assertRaises(Exception, self.cellule.ajouterLien, lien)
def test_ajouterLien_ok(self): cellule2 = Cellule(numero=2, attaque=10, defense=5, attaqueMax=20, defenseMax=30, production=2, couleurJoueur=0, x=10, y=60, rayon=40) lien = Lien(self.cellule, cellule2, 666) self.cellule.ajouterLien(lien) # on regarde si le lien ajouté est bien dans la liste des liens de la cellule self.assertIn(lien, self.cellule.liens)
def __init__( self, parent ): # Create an input command line and an output line # separated by an adjustable splitter # Qt.QSplitter.__init__( self, parent ) inputLine = Qt.QLineEdit( self ) outputLine = Qt.QLineEdit( self ) # Configure the widgets # self.setSizePolicy( Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed ) inputLine.palette().setColor( Qt.QPalette.Base, Qt.QColor( 200, 200, 200 ) ) inputLine.palette().setColor( Qt.QPalette.Text, Qt.QColor( 0, 0, 0 ) ) outputLine.setReadOnly( True ) # Signals / Slots # logSIP = Cellule.toSIP( Cellule.appli.log ) Qt.QObject.connect( logSIP, Qt.SIGNAL( 'textAdded(const QString&)' ), outputLine, Qt.SLOT( 'setText(const QString&)' ) )
def setAsCurrent( self ): toolName = self.text() Cellule.appli.toolManager.setCurrentTool( Cellule.fromSIP( toolName ) )
class TestCellule(unittest.TestCase): # appelée avant chaque cas de test def setUp(self): # on crée la cellule qui sera testée self.cellule = Cellule(numero=1, attaque=0, defense=0, attaqueMax=10, defenseMax=30, production=3, couleurJoueur=2, x=100, y=100, rayon=50) def test_init_1(self): pass # ---------------------- test de la fonction 'setAttaque' ---------------------- # un fonctionnement normal def test_setAttaque_ok(self): valeur = 5 self.cellule.setAttaque(valeur) self.assertEqual(self.cellule.getAttaque(), valeur) # entrée d'une valeur non entière # excpetion attendue def test_setAttaque_pasEntier(self): self.assertRaises(Exception, self.cellule.setAttaque, "Test") # entrée d'une valeur négative # excpetion attendue def test_setAttaque_negatif(self): self.assertRaises(Exception, self.cellule.setAttaque, -1) # entrée d'une valeur trop grande # excpetion attendue def test_setAttaque_tropGrand(self): valeur = self.cellule.getAttaqueMax() + 1 self.assertRaises(Exception, self.cellule.setAttaque, valeur) # ---------------------- test de la fonction 'setDefence' ---------------------- # un fonctionnement normal def test_setDefense_ok(self): valeur = 7 self.cellule.setDefense(valeur) self.assertEqual(self.cellule.getDefense(), valeur) # entrée d'une valeur non entière # excpetion attendue def test_setDefense_pasEntier(self): self.assertRaises(Exception, self.cellule.setDefense, "Test autre") # entrée d'une valeur négative # excpetion attendue def test_setDefense_negatif(self): self.assertRaises(Exception, self.cellule.setDefense, -10) # entrée d'une valeur trop grande # excpetion attendue def test_setDefense_tropGrand(self): valeur = self.cellule.getDefenseMax() + 36 self.assertRaises(Exception, self.cellule.setDefense, valeur) # ---------------------- test de la fonction 'setCouleurJoueur' ---------------------- # un fonctionnement normal def test_setCouleurJoueur_ok(self): valeur = 2 self.cellule.setCouleurJoueur(valeur) self.assertEqual(self.cellule.getCouleurJoueur(), valeur) # entrée d'une valeur non entière # exception attendue def test_setCouleurJoueur_pasEntier(self): self.assertRaises(Exception, self.cellule.setCouleurJoueur, "pas une couleur") # entrée d'une valeur négative # exception attendue def test_setCouleurJoueur_negatif(self): self.assertRaises(Exception, self.cellule.setCouleurJoueur, -9) # ---------------------- test de la fonction 'ajouterLien' ---------------------- # un fonctionnement normal def test_ajouterLien_ok(self): cellule2 = Cellule(numero=2, attaque=10, defense=5, attaqueMax=20, defenseMax=30, production=2, couleurJoueur=0, x=10, y=60, rayon=40) lien = Lien(self.cellule, cellule2, 666) self.cellule.ajouterLien(lien) # on regarde si le lien ajouté est bien dans la liste des liens de la cellule self.assertIn(lien, self.cellule.liens) # ajout d'une valeur autre qu'un Lien # exception attendue def test_ajouterLien_pasLien(self): self.assertRaises(Exception, self.cellule.ajouterLien, "pas un lien") # ajouter un lien à une cellule, cette dernière ne faisant pas partie de ce lien (donc pas l'un des bords de l'arête) # exception attendue def test_ajouterLien_pasCellule(self): cellule1 = Cellule(numero=0, attaque=0, defense=5, attaqueMax=25, defenseMax=30, production=2, couleurJoueur=8, x=10, y=60, rayon=45) cellule2 = Cellule(numero=2, attaque=10, defense=8, attaqueMax=20, defenseMax=36, production=4, couleurJoueur=0, x=10, y=60, rayon=40) lien = Lien(cellule1, cellule2, 99) self.assertRaises(Exception, self.cellule.ajouterLien, lien)
import Cellule import Actions import MainMenuBar import MainToolBar import View2D import GraphEditor import Console import CommandLine from PyQt4 import Qt # Get application main window as a SIP object # mainWinSIP = Cellule.toSIP( Cellule.appli.mainWin, Qt.QMainWindow ) Actions.createMainWindowActions( mainWinSIP ) # Create menus # mainMenuBar = MainMenuBar.Widget( mainWinSIP ) mainWinSIP.setMenuBar( mainMenuBar ) # Create main toolbar # MainToolBar.init( mainWinSIP ) # Create 2D view # view2D = View2D.Widget( mainWinSIP )
def __init__( self, parent ): Qt.QWidget.__init__( self, parent ) # Menus # menuBar = Qt.QMenuBar( self ) fileMenu = menuBar.addMenu( 'File' ) editMenu = menuBar.addMenu( 'Edit' ) optionsMenu = menuBar.addMenu( 'Options' ) openScriptAction = fileMenu .addAction( 'Open script...' ) saveScriptAction = fileMenu .addAction( 'Save script as...' ) executeAction = editMenu .addAction( 'Execute' ) clearOutputAction = editMenu .addAction( 'Clear output' ) clearInputAction = editMenu .addAction( 'Clear input' ) clearAllAction = editMenu .addAction( 'Clear all' ) self.showStackTrace = optionsMenu.addAction( 'Show stack trace' ) self.showStackTrace.setCheckable( True ) self.showStackTrace.setChecked ( False ) openScriptAction .setIcon ( Qt.QIcon( 'icons/16x16/document-open.png' ) ) saveScriptAction .setIcon ( Qt.QIcon( 'icons/16x16/document-save-as.png' ) ) executeAction .setIcon ( Qt.QIcon( 'icons/16x16/go-jump-locationbar.png' ) ) clearOutputAction .setIcon ( Qt.QIcon( 'icons/16x16/edit-clear-locationbar-ltr.png' ) ) clearInputAction .setIcon ( Qt.QIcon( 'icons/16x16/edit-clear-locationbar-rtl.png' ) ) clearAllAction .setIcon ( Qt.QIcon( 'icons/16x16/trash-empty.png' ) ) openScriptAction .setStatusTip( 'Load a script file into the console' ) saveScriptAction .setStatusTip( 'Save the console input to a file' ) executeAction .setStatusTip( 'Execute console input selected code ( whole if no selection )' ) clearOutputAction .setStatusTip( 'Clear console output' ) clearInputAction .setStatusTip( 'Clear console input' ) clearAllAction .setStatusTip( 'Clear console input and output' ) self.showStackTrace.setStatusTip( 'Detail error location when printing error messages' ) executeAction .setShortcut ( Qt.QKeySequence( 'Ctrl+Return' ) ) # Output and Input # splitter = Qt.QSplitter( Qt.Qt.Vertical, self ) self.output = Qt.QTextEdit( splitter ) self.input = InputWidget ( splitter ) self.output.setReadOnly ( True ) self.input.setAcceptRichText( False ) # Layout # layout = Qt.QVBoxLayout( self ) layout.addWidget( menuBar ) layout.addWidget( splitter ) # Signal / Slots # logSIP = Cellule.toSIP( Cellule.appli.log ) scriptEngineSIP = Cellule.toSIP( Cellule.appli.scriptEngine ) Qt.QObject.connect( openScriptAction, Qt.SIGNAL( 'triggered()' ), self.openScript ) Qt.QObject.connect( saveScriptAction, Qt.SIGNAL( 'triggered()' ), self.saveScript ) Qt.QObject.connect( executeAction, Qt.SIGNAL( 'triggered()' ), self.input.requestExecution ) Qt.QObject.connect( clearOutputAction, Qt.SIGNAL( 'triggered()' ), self.output, Qt.SLOT( 'clear()' ) ) Qt.QObject.connect( clearInputAction, Qt.SIGNAL( 'triggered()' ), self.input, Qt.SLOT( 'clear()' ) ) Qt.QObject.connect( clearAllAction, Qt.SIGNAL( 'triggered()' ), self.output, Qt.SLOT( 'clear()' ) ) Qt.QObject.connect( clearAllAction, Qt.SIGNAL( 'triggered()' ), self.input, Qt.SLOT( 'clear()' ) ) Qt.QObject.connect( logSIP, Qt.SIGNAL( 'htmlAdded(const QString&)' ), self.output, Qt.SLOT( 'append(const QString&)' ) ) Qt.QObject.connect( self.input, Qt.SIGNAL( 'executionRequested' ), self.execute )
def __init__(self, parent): Qt.QWidget.__init__(self, parent) menuBar = Qt.QMenuBar(self) # Display menu # displayMenu = menuBar.addMenu("Display") displayLevelGroup = Qt.QActionGroup(displayMenu) displayLevelPointAction = Qt.QAction("Point", displayLevelGroup) displayLevelWireframeAction = Qt.QAction("Wireframe", displayLevelGroup) displayLevelBSplineAction = Qt.QAction("BSpline", displayLevelGroup) displayLevelShadedAction = Qt.QAction("Shaded", displayLevelGroup) displayLevelPointAction.setCheckable(True) displayLevelWireframeAction.setCheckable(True) displayLevelBSplineAction.setCheckable(True) displayLevelShadedAction.setCheckable(True) displayLevelShadedAction.setChecked(True) showSeedsAction = Qt.QAction("Show seeds", displayMenu) showDelauneyAction = Qt.QAction("Show Delauney", displayMenu) showSeedsAction.setCheckable(True) showDelauneyAction.setCheckable(True) displayMenu.addAction(displayLevelPointAction) displayMenu.addAction(displayLevelWireframeAction) displayMenu.addAction(displayLevelBSplineAction) displayMenu.addAction(displayLevelShadedAction) displayMenu.addAction(showSeedsAction) displayMenu.addAction(showDelauneyAction) # Render menu # renderMenu = menuBar.addMenu("Render") showRenderSettingsAction = Qt.QAction("Settings...", renderMenu) saveRenderedImageAsAction = Qt.QAction("Save image as...", renderMenu) # renderMenu.addAction( showRenderSettingsAction ) renderMenu.addAction(saveRenderedImageAsAction) # 2D View # self.view2D = Cellule.appli.createView2D(Cellule.fromSIP(self)) view2DSIP = Cellule.toSIP(self.view2D, Qt.QWidget) # Layout # layout = Qt.QVBoxLayout(self) layout.addWidget(menuBar) layout.addWidget(view2DSIP) # Signals / Slots # Qt.QObject.connect(displayLevelPointAction, Qt.SIGNAL("triggered()"), self.view2D.setDisplayLevelPoint) Qt.QObject.connect(displayLevelWireframeAction, Qt.SIGNAL("triggered()"), self.view2D.setDisplayLevelWireframe) Qt.QObject.connect(displayLevelShadedAction, Qt.SIGNAL("triggered()"), self.view2D.setDisplayLevelShaded) Qt.QObject.connect(displayLevelBSplineAction, Qt.SIGNAL("triggered()"), self.view2D.setDisplayLevelBSpline) Qt.QObject.connect(showSeedsAction, Qt.SIGNAL("toggled(bool)"), self.view2D.displaySeeds) Qt.QObject.connect(showDelauneyAction, Qt.SIGNAL("toggled(bool)"), self.view2D.displayDelauney) Qt.QObject.connect(showRenderSettingsAction, Qt.SIGNAL("triggered()"), self.showRenderSettings) Qt.QObject.connect(saveRenderedImageAsAction, Qt.SIGNAL("triggered()"), self.saveRenderedImageAs)
def initialiserMatch(self, init_string): """ Initialise le robot pour un match. A appeler dans la procédure 'init_pooo(init_string)' exemple : "INIT20ac18ab-6d18-450e-94af-bee53fdc8fcaTO6[2];1;3CELLS:1(23,9)'2'30'8'I,2(41,55)'1'30'8'II,3(23,103)'1'20'5'I;2LINES:1@3433OF2,1@6502OF3" :param init_string: chaîne regroupant les informations envoyées par le serveur pour l'initialisation d'un nouveau match, sous la forme INIT. :type init_string: str """ logging.info("==== initialisation") regex_init = re.compile( r"INIT(?P<id_match>.{8}-.{4}-.{4}-.{4}-.{12})TO(?P<nb_joueurs>[0-9]*)\[(?P<maCouleur>[0-9]*)\];(?P<vitesse>[0-9]*);(?P<nbCellules>[0-9]*)CELLS:(?P<cellules>([0-9]+\([0-9]+,[0-9]+\)'[0-9]+'[0-9]+'[0-9]+'I+,?)*);(?P<nbLines>[0-9]*)LINES:(?P<lignes>([0-9]+@[0-9]+OF[0-9]+,?)*)" ) informations = regex_init.match(init_string) if (not informations): raise Exception( "la chaine entrée est invalide (ne correspond pas à la regex)") # on récupère autant d'informations que possible sur la chaine d'origine self.vitesse = int(informations.group('vitesse')) self.id_match = informations.group('id_match') self.maCouleur = int(informations.group('maCouleur')) self.nbJoueursInitial = int(informations.group('nb_joueurs')) self.nbJoueurs = self.nbJoueursInitial # création d'un terrain vide, que l'on remplira au fur et à mesure self.terrain = te.Terrain() nbCellules = informations.group("nbCellules") # on trouve toutes les correspondances au pattern correspondant à la description d'une cellule # et pour chaque correspondance, on en extrait les informations de la cellule regex_cellules = re.compile( r"[0-9]+\([0-9]+,[0-9]+\)'[0-9]+'[0-9]+'[0-9]+'I+") regex_uneCellule = re.compile( r"(?P<id_cellule>[0-9]+)\((?P<x>[0-9]+),(?P<y>[0-9]+)\)'(?P<rayon>[0-9]+)'(?P<maxATT>[0-9]+)'(?P<maxDEF>[0-9]+)'(?P<production>I+)" ) # on ne peut pas séparer ici pas un "," => donc on n'utilise pas re.split() for chaine in regex_cellules.findall(informations.group('cellules')): ifs = regex_uneCellule.match(chaine) try: numero = int(ifs.group('id_cellule')) attaque, defense, couleurJoueur = 0, 0, -1 # cellule neutre, n'a ni attaque, ni defense attaqueMax = int(ifs.group('maxATT')) defenseMax = int(ifs.group('maxDEF')) production = len( ifs.group('production')) # on compte le nombre de I x = int(ifs.group('x')) y = int(ifs.group('y')) rayon = int(ifs.group('rayon')) cellule = ce.Cellule(numero, attaque, defense, attaqueMax, defenseMax, production, couleurJoueur, x, y, rayon) self.terrain.ajouterCellule(cellule) except Exception as e: logging.info( "======== /!\ IMPOSSIBLE DE CREER UNE CELLULE (initialiserMatch) : " + e) nbLines = informations.group("nbLines") # on fait de même pour les liens entres les cellules regex_unLien = re.compile( r"(?P<id_cellule_u>[0-9]+)@(?P<distance>[0-9]+)OF(?P<id_cellule_v>[0-9]+)" ) for chaine in re.split(",", informations.group("lignes")): try: ifs = regex_unLien.match(chaine) numero_u = int(ifs.group('id_cellule_u')) numero_v = int(ifs.group('id_cellule_v')) distance = int(ifs.group('distance')) lien = li.Lien(self.terrain.getCellule(numero_u), self.terrain.getCellule(numero_v), distance) self.terrain.ajouterLien(lien) except Exception as e: logging.info("======== /!\ IMPOSSIBLE DE CREER LE LIEN : " + e) self.peut_jouer = True self.partie_en_cours = True pass
def setUp(self): # on crée la cellule qui sera testée self.cellule = Cellule( numero = 1, attaque = 0, defense = 0, attaqueMax = 10, defenseMax = 30, production = 3, couleurJoueur = 2, x = 100, y = 100, rayon = 50 )
class TestCellule(unittest.TestCase): # appelée avant chaque cas de test def setUp(self): # on crée la cellule qui sera testée self.cellule = Cellule( numero = 1, attaque = 0, defense = 0, attaqueMax = 10, defenseMax = 30, production = 3, couleurJoueur = 2, x = 100, y = 100, rayon = 50 ) def test_init_1(self): pass # ---------------------- test de la fonction 'setAttaque' ---------------------- # un fonctionnement normal def test_setAttaque_ok(self): valeur = 5 self.cellule.setAttaque(valeur) self.assertEqual( self.cellule.getAttaque() , valeur ) # entrée d'une valeur non entière # excpetion attendue def test_setAttaque_pasEntier(self): self.assertRaises( Exception, self.cellule.setAttaque, "Test" ) # entrée d'une valeur négative # excpetion attendue def test_setAttaque_negatif(self): self.assertRaises( Exception, self.cellule.setAttaque, -1 ) # entrée d'une valeur trop grande # excpetion attendue def test_setAttaque_tropGrand(self): valeur = self.cellule.getAttaqueMax() + 1 self.assertRaises( Exception, self.cellule.setAttaque, valeur ) # ---------------------- test de la fonction 'setDefence' ---------------------- # un fonctionnement normal def test_setDefense_ok(self): valeur = 7 self.cellule.setDefense(valeur) self.assertEqual( self.cellule.getDefense() , valeur ) # entrée d'une valeur non entière # excpetion attendue def test_setDefense_pasEntier(self): self.assertRaises( Exception, self.cellule.setDefense, "Test autre" ) # entrée d'une valeur négative # excpetion attendue def test_setDefense_negatif(self): self.assertRaises( Exception, self.cellule.setDefense, -10 ) # entrée d'une valeur trop grande # excpetion attendue def test_setDefense_tropGrand(self): valeur = self.cellule.getDefenseMax() + 36 self.assertRaises( Exception, self.cellule.setDefense, valeur ) # ---------------------- test de la fonction 'setCouleurJoueur' ---------------------- # un fonctionnement normal def test_setCouleurJoueur_ok(self): valeur = 2 self.cellule.setCouleurJoueur(valeur) self.assertEqual( self.cellule.getCouleurJoueur() , valeur ) # entrée d'une valeur non entière # exception attendue def test_setCouleurJoueur_pasEntier(self): self.assertRaises( Exception, self.cellule.setCouleurJoueur, "pas une couleur" ) # entrée d'une valeur négative # exception attendue def test_setCouleurJoueur_negatif(self): self.assertRaises( Exception, self.cellule.setCouleurJoueur, -9 ) # ---------------------- test de la fonction 'ajouterLien' ---------------------- # un fonctionnement normal def test_ajouterLien_ok(self): cellule2 = Cellule( numero = 2, attaque = 10, defense = 5, attaqueMax = 20, defenseMax = 30, production = 2, couleurJoueur = 0, x = 10, y = 60, rayon = 40 ) lien = Lien( self.cellule, cellule2, 666 ) self.cellule.ajouterLien( lien ) # on regarde si le lien ajouté est bien dans la liste des liens de la cellule self.assertIn( lien, self.cellule.liens ) # ajout d'une valeur autre qu'un Lien # exception attendue def test_ajouterLien_pasLien(self): self.assertRaises( Exception, self.cellule.ajouterLien, "pas un lien" ) # ajouter un lien à une cellule, cette dernière ne faisant pas partie de ce lien (donc pas l'un des bords de l'arête) # exception attendue def test_ajouterLien_pasCellule(self): cellule1 = Cellule( numero = 0, attaque = 0, defense = 5, attaqueMax = 25, defenseMax = 30, production = 2, couleurJoueur = 8, x = 10, y = 60, rayon = 45 ) cellule2 = Cellule( numero = 2, attaque = 10, defense = 8, attaqueMax = 20, defenseMax = 36, production = 4, couleurJoueur = 0, x = 10, y = 60, rayon = 40 ) lien = Lien( cellule1, cellule2, 99 ) self.assertRaises( Exception, self.cellule.ajouterLien, lien )
def create( self ): nodeTypeName = self.text() Cellule.appli.scene.createNode( Cellule.fromSIP( nodeTypeName ) )