class GuiRingPlayerStats(QSplitter): def __init__(self, config, querylist, mainwin, debug=True): QSplitter.__init__(self, None) self.debug = debug self.conf = config self.main_window = mainwin self.sql = querylist self.liststore = [ ] # gtk.ListStore[] stores the contents of the grids self.listcols = [ ] # gtk.TreeViewColumn[][] stores the columns in the grids self.MYSQL_INNODB = 2 self.PGSQL = 3 self.SQLITE = 4 # create new db connection to avoid conflicts with other threads self.db = Database.Database(self.conf, sql=self.sql) self.cursor = self.db.cursor settings = {} settings.update(self.conf.get_db_parameters()) settings.update(self.conf.get_import_parameters()) settings.update(self.conf.get_default_paths()) # text used on screen stored here so that it can be configured self.filterText = { 'handhead': _('Hand Breakdown for all levels listed above') } filters_display = { "Heroes": True, "Sites": True, "Games": True, "Currencies": True, "Limits": True, "LimitSep": True, "LimitType": True, "Type": True, "Seats": True, "SeatSep": True, "Dates": True, "Groups": True, "GroupsAll": True, "Button1": True, "Button2": True } self.filters = Filters.Filters(self.db, display=filters_display) self.filters.registerButton1Name(_("Filters")) self.filters.registerButton1Callback(self.showDetailFilter) self.filters.registerButton2Name(_("Refresh Stats")) self.filters.registerButton2Callback(self.refreshStats) scroll = QScrollArea() scroll.setWidget(self.filters) # ToDo: store in config # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed(summary then position), column heading, xalignment, formatting, celltype self.columns = self.conf.get_gui_cash_stat_params() # Detail filters: This holds the data used in the popup window, extra values are # added at the end of these lists during processing # sql test, screen description, min, max self.handtests = [ # already in filter class : ['h.seats', 'Number of Players', 2, 10] ['gt.maxSeats', 'Size of Table', 2, 10], ['h.playersVpi', 'Players who VPI', 0, 10], ['h.playersAtStreet1', 'Players at Flop', 0, 10], ['h.playersAtStreet2', 'Players at Turn', 0, 10], ['h.playersAtStreet3', 'Players at River', 0, 10], ['h.playersAtStreet4', 'Players at Street7', 0, 10], ['h.playersAtShowdown', 'Players at Showdown', 0, 10], ['h.street0Raises', 'Bets to See Flop', 0, 5], ['h.street1Raises', 'Bets to See Turn', 0, 5], ['h.street2Raises', 'Bets to See River', 0, 5], ['h.street3Raises', 'Bets to See Street7', 0, 5], ['h.street4Raises', 'Bets to See Showdown', 0, 5] ] self.cardstests = [ [Card.DATABASE_FILTERS['pair'], _('Pocket pairs')], [Card.DATABASE_FILTERS['suited'], _('Suited')], [ Card.DATABASE_FILTERS['suited_connectors'], _('Suited connectors') ], [Card.DATABASE_FILTERS['offsuit'], _('Offsuit')], [ Card.DATABASE_FILTERS['offsuit_connectors'], _('Offsuit connectors') ], ] self.stats_frame = None self.stats_vbox = None self.detailFilters = [] # the data used to enhance the sql select self.cardsFilters = [] self.stats_frame = QFrame() self.stats_frame.setLayout(QVBoxLayout()) self.stats_vbox = QSplitter(Qt.Vertical) self.stats_frame.layout().addWidget(self.stats_vbox) self.addWidget(scroll) self.addWidget(self.stats_frame) self.setStretchFactor(0, 0) self.setStretchFactor(1, 1) # Make sure Hand column is not displayed. hand_column = (x for x in self.columns if x[0] == 'hand').next() hand_column[colshowsumm] = hand_column[colshowposn] = False # If rfi and steal both on for summaries, turn rfi off. rfi_column = (x for x in self.columns if x[0] == 'rfi').next() steals_column = (x for x in self.columns if x[0] == 'steals').next() if rfi_column[colshowsumm] and steals_column[colshowsumm]: rfi_column[colshowsumm] = False # If rfi and steal both on for position breakdowns, turn steals off. if rfi_column[colshowposn] and steals_column[colshowposn]: steals_column[colshowposn] = False def refreshStats(self, checkState): self.liststore = [] self.listcols = [] self.stats_frame.layout().removeWidget(self.stats_vbox) self.stats_vbox.setParent(None) self.stats_vbox = QSplitter(Qt.Vertical) self.stats_frame.layout().addWidget(self.stats_vbox) self.fillStatsFrame(self.stats_vbox) if self.liststore: topsize = self.stats_vbox.widget(0).sizeHint().height() self.stats_vbox.setSizes( [topsize, self.stats_vbox.height() - topsize]) self.stats_vbox.setStretchFactor(0, 0) self.stats_vbox.setStretchFactor(1, 1) def fillStatsFrame(self, vbox): sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() seats = self.filters.getSeats() groups = self.filters.getGroups() dates = self.filters.getDates() games = self.filters.getGames() currencies = self.filters.getCurrencies() sitenos = [] playerids = [] # Which sites are selected? for site in sites: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") sitenos = [2] if not playerids: print _("No player ids found") return if not limits: print _("No limits found") return self.createStatsTable(vbox, playerids, sitenos, limits, seats, groups, dates, games, currencies) def createStatsTable(self, vbox, playerids, sitenos, limits, seats, groups, dates, games, currencies): startTime = time() show_detail = True # # Display summary table at top of page # # 3rd parameter passes extra flags, currently includes: # # holecards - whether to display card breakdown (True/False) # # numhands - min number hands required when displaying all players # # gridnum - index for grid data structures flags = [False, self.filters.getNumHands(), 0] self.addGrid(vbox, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, groups, dates, games, currencies) if 'allplayers' in groups: # can't currently do this combination so skip detailed table show_detail = False if show_detail: # Separator frame = QWidget() vbox2 = QVBoxLayout() vbox2.setContentsMargins(0, 0, 0, 0) frame.setLayout(vbox2) vbox.addWidget(frame) heading = QLabel(self.filterText['handhead']) heading.setAlignment(Qt.AlignHCenter) vbox2.addWidget(heading) # Detailed table flags[0] = True flags[2] = 1 self.addGrid(vbox2, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, groups, dates, games, currencies) self.db.rollback() print( _("Stats page displayed in %4.2f seconds") % (time() - startTime)) def addGrid(self, vbox, query, flags, playerids, sitenos, limits, seats, groups, dates, games, currencies): sqlrow = 0 if not flags: holecards, grid = False, 0 else: holecards, grid = flags[0], flags[2] tmp = self.sql.query[query] tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, groups, dates, games, currencies) self.cursor.execute(tmp) result = self.cursor.fetchall() colnames = [desc[0].lower() for desc in self.cursor.description] # pre-fetch some constant values: colshow = colshowsumm if 'posn' in groups: colshow = colshowposn self.cols_to_show = [x for x in self.columns if x[colshow]] hgametypeid_idx = colnames.index('hgametypeid') assert len(self.liststore) == grid, "len(self.liststore)=" + str( len(self.liststore)) + " grid-1=" + str(grid) view = QTableView() self.liststore.append( QStandardItemModel(0, len(self.cols_to_show), view)) self.liststore[grid].setSortRole(Qt.UserRole) view.setModel(self.liststore[grid]) view.verticalHeader().hide() vbox.addWidget(view) self.listcols.append([]) # Create header row eg column: ("game", True, "Game", 0.0, "%s") for col, column in enumerate(self.cols_to_show): if column[colalias] == 'game' and holecards: s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading] else: s = column[colheading] self.listcols[grid].append(s) self.liststore[grid].setHorizontalHeaderLabels(self.listcols[grid]) rows = len(result) # +1 for title row while sqlrow < rows: treerow = [] for col, column in enumerate(self.cols_to_show): if column[colalias] in colnames: value = result[sqlrow][colnames.index(column[colalias])] if column[colalias] == 'plposition': if value == 'B': value = 'BB' elif value == 'S': value = 'SB' elif value == '0': value = 'Btn' else: if column[colalias] == 'game': if holecards: value = Card.decodeStartHandValue( result[sqlrow][colnames.index('category')], result[sqlrow][hgametypeid_idx]) else: minbb = result[sqlrow][colnames.index( 'minbigblind')] maxbb = result[sqlrow][colnames.index( 'maxbigblind')] value = result[sqlrow][colnames.index('limittype')] + ' ' \ + result[sqlrow][colnames.index('category')].title() + ' ' \ + result[sqlrow][colnames.index('name')] + ' ' \ + result[sqlrow][colnames.index('currency')] + ' ' if 100 * int(minbb / 100.0) != minbb: value += '%.2f' % (minbb / 100.0) else: value += '%.0f' % (minbb / 100.0) if minbb != maxbb: if 100 * int(maxbb / 100.0) != maxbb: value += ' - %.2f' % (maxbb / 100.0) else: value += ' - %.0f' % (maxbb / 100.0) ante = result[sqlrow][colnames.index('ante')] if ante > 0: value += ' ante: %.2f' % (ante / 100.0) if result[sqlrow][colnames.index('fast')] == 1: value += ' ' + fast_names[result[sqlrow][ colnames.index('name')]] else: continue item = QStandardItem('') sortValue = -1e9 if value is not None and value != -999: item = QStandardItem(column[colformat] % value) if column[colalias] == 'game' and holecards: if result[sqlrow][colnames.index( 'category')] == 'holdem': sortValue = 1000 * ranks[value[0]] + 10 * ranks[ value[1]] + (1 if len(value) == 3 and value[2] == 's' else 0) else: sortValue = -1 elif column[colalias] in ('game', 'pname'): sortValue = value elif column[colalias] == 'plposition': sortValue = [ 'BB', 'SB', 'Btn', '1', '2', '3', '4', '5', '6', '7' ].index(value) else: sortValue = float(value) item.setData(sortValue, Qt.UserRole) item.setEditable(False) if col != 0: item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) if column[colalias] != 'game': item.setToolTip('<big>%s for %s</big><br/><i>%s</i>' % (column[colheading], treerow[0].text(), onlinehelp[column[colheading]])) treerow.append(item) self.liststore[grid].appendRow(treerow) sqlrow += 1 view.resizeColumnsToContents() view.setSortingEnabled( True ) # do this after resizing columns, otherwise it leaves room for the sorting triangle in every heading view.resizeColumnToContents( 0 ) # we want room for the sorting triangle in column 0 where it starts. view.resizeRowsToContents() def refineQuery(self, query, flags, playerids, sitenos, limits, seats, groups, dates, games, currencies): having = '' if not flags: holecards = False numhands = 0 else: holecards = flags[0] numhands = flags[1] colshow = colshowsumm if 'posn' in groups: colshow = colshowposn pname_column = (x for x in self.columns if x[0] == 'pname').next() if 'allplayers' in groups: nametest = "(hp.playerId)" if holecards or 'posn' in groups: pname = "'all players'" # set flag in self.columns to not show player name column pname_column[colshow] = False # can't do this yet (re-write doing more maths in python instead of sql?) if numhands: nametest = "(-1)" else: pname = "p.name" # set flag in self.columns to show player name column pname_column[colshow] = True if numhands: having = ' and count(1) > %d ' % (numhands, ) else: if playerids: nametest = str(tuple(playerids)) nametest = nametest.replace("L", "") nametest = nametest.replace(",)", ")") else: nametest = "1 = 2" pname = "p.name" # set flag in self.columns to not show player name column pname_column[colshow] = False query = query.replace("<player_test>", nametest) query = query.replace("<playerName>", pname) query = query.replace("<havingclause>", having) gametest = "" for m in self.filters.display.items(): if m[0] == 'Games' and m[1]: if len(games) > 0: gametest = str(tuple(games)) gametest = gametest.replace("L", "") gametest = gametest.replace(",)", ")") gametest = gametest.replace("u'", "'") gametest = "and gt.category in %s" % gametest else: gametest = "and gt.category IS NULL" query = query.replace("<game_test>", gametest) currencytest = str(tuple(currencies)) currencytest = currencytest.replace(",)", ")") currencytest = currencytest.replace("u'", "'") currencytest = "AND gt.currency in %s" % currencytest query = query.replace("<currency_test>", currencytest) sitetest = "" for m in self.filters.display.items(): if m[0] == 'Sites' and m[1]: if len(sitenos) > 0: sitetest = str(tuple(sitenos)) sitetest = sitetest.replace("L", "") sitetest = sitetest.replace(",)", ")") sitetest = sitetest.replace("u'", "'") sitetest = "and gt.siteId in %s" % sitetest else: sitetest = "and gt.siteId IS NULL" query = query.replace("<site_test>", sitetest) if seats: query = query.replace( '<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to'])) if 'seats' in groups: query = query.replace('<groupbyseats>', ',h.seats') query = query.replace('<orderbyseats>', ',h.seats') else: query = query.replace('<groupbyseats>', '') query = query.replace('<orderbyseats>', '') else: query = query.replace('<seats_test>', 'between 0 and 100') query = query.replace('<groupbyseats>', '') query = query.replace('<orderbyseats>', '') bbtest = self.filters.get_limits_where_clause(limits) query = query.replace("<gtbigBlind_test>", bbtest) if holecards: # re-use level variables for hole card query query = query.replace("<hgametypeId>", "hp.startcards") query = query.replace( "<orderbyhgametypeId>", ",case when floor((hp.startcards-1)/13) >= mod((hp.startcards-1),13) then hp.startcards + 0.1 " + " else 13*mod((hp.startcards-1),13) + floor((hp.startcards-1)/13) + 1 " + " end desc ") else: query = query.replace("<orderbyhgametypeId>", "") groupLevels = 'limits' not in groups if groupLevels: query = query.replace( "<hgametypeId>", "p.name" ) # need to use p.name for sqlite posn stats to work else: query = query.replace("<hgametypeId>", "h.gametypeId") # process self.detailFilters (a list of tuples) flagtest = '' if self.detailFilters: for f in self.detailFilters: if len(f) == 3: # X between Y and Z flagtest += ' and %s between %s and %s ' % (f[0], str( f[1]), str(f[2])) query = query.replace("<flagtest>", flagtest) if self.cardsFilters: cardstests = [] for cardFilter in self.cardsFilters: cardstests.append(cardFilter) cardstests = ''.join(('and (', ' or '.join(cardstests), ')')) else: cardstests = '' query = query.replace("<cardstest>", cardstests) # allow for differences in sql cast() function: if self.db.backend == self.MYSQL_INNODB: query = query.replace("<signed>", 'signed ') else: query = query.replace("<signed>", '') # Filter on dates query = query.replace( "<datestest>", " between '" + dates[0] + "' and '" + dates[1] + "'") # Group by position? plposition_column = (x for x in self.columns if x[0] == 'plposition').next() if 'posn' in groups: query = query.replace("<position>", "hp.position") plposition_column[colshow] = True else: query = query.replace("<position>", "gt.base") plposition_column[colshow] = False return (query) def showDetailFilter(self, checkState): detailDialog = QDialog(self.main_window) detailDialog.setWindowTitle(_("Detailed Filters")) handbox = QVBoxLayout() detailDialog.setLayout(handbox) label = QLabel(_("Hand Filters:")) handbox.addWidget(label) label.setAlignment(Qt.AlignCenter) grid = QGridLayout() handbox.addLayout(grid) for row, htest in enumerate(self.handtests): cb = QCheckBox() lbl_from = QLabel(htest[1]) lbl_tween = QLabel(_('between')) lbl_to = QLabel(_('and')) sb1 = QSpinBox() sb1.setRange(0, 10) sb1.setValue(htest[2]) sb2 = QSpinBox() sb2.setRange(2, 10) sb2.setValue(htest[3]) for df in self.detailFilters: if df[0] == htest[0]: cb.setChecked(True) break grid.addWidget(cb, row, 0) grid.addWidget(lbl_from, row, 1, Qt.AlignLeft) grid.addWidget(lbl_tween, row, 2) grid.addWidget(sb1, row, 3) grid.addWidget(lbl_to, row, 4) grid.addWidget(sb2, row, 5) htest[4:7] = [cb, sb1, sb2] label = QLabel(_('Restrict to hand types:')) handbox.addWidget(label) for ctest in self.cardstests: hbox = QHBoxLayout() handbox.addLayout(hbox) cb = QCheckBox() if ctest[0] in self.cardsFilters: cb.setChecked(True) label = QLabel(ctest[1]) hbox.addWidget(cb) hbox.addWidget(label) ctest[2:3] = [cb] btnBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) handbox.addWidget(btnBox) btnBox.accepted.connect(detailDialog.accept) btnBox.rejected.connect(detailDialog.reject) response = detailDialog.exec_() if response: self.detailFilters = [] for ht in self.handtests: if ht[4].isChecked(): self.detailFilters.append( (ht[0], ht[5].value(), ht[6].value())) ht[2], ht[3] = ht[5].value(), ht[6].value() self.cardsFilters = [] for ct in self.cardstests: if ct[2].isChecked(): self.cardsFilters.append(ct[0]) self.refreshStats(None)
def initWin(self): iptGrid = QGridLayout() title = Text("TSP", (255, 0, 0), 16, "center") pic = QPixmap("C:\\tsp.png") picLbl = QLabel() picLbl.setPixmap(pic) picLbl.setScaledContents(True) titleLayout = QVBoxLayout() titleLayout.addWidget(title) titleLayout.addWidget(picLbl) titleFrame = QFrame() titleFrame.setFrameShape(QFrame.StyledPanel) titleFrame.setAutoFillBackground(True) p5 = titleFrame.palette() p5.setColor(titleFrame.backgroundRole(), QColor(255, 255, 255)) titleFrame.setPalette(p5) titleFrame.setLayout(titleLayout) iptTitle = Text("Program Input", (255, 0, 0), 12, "center") iptTxt1 = QLabel("Cities No:") iptTxt1.setFont(QFont("Decorative", 12)) iptTxt2 = QLabel("start:") iptTxt2.setFont(QFont("Decorative", 12)) self.iptEdt1 = QLineEdit() self.iptEdt1.textChanged[str].connect(self.get_input) self.iptEdt2 = QLineEdit() self.iptEdt2.textChanged[str].connect(self.get_input) self.iptBtn1 = QPushButton("Build") self.iptBtn1.clicked.connect(self.bulid_map) self.iptBtn2 = QPushButton("Rturn") self.iptBtn2.clicked.connect(self.get_initial) iptH = QHBoxLayout() iptH.addWidget(self.iptBtn1) iptH.addWidget(self.iptBtn2) iptGrid.addWidget(iptTitle, 1, 0, 1, 5) iptGrid.addWidget(iptTxt1, 2, 0) iptGrid.addWidget(self.iptEdt1, 2, 1) iptGrid.addWidget(iptTxt2, 3, 0) iptGrid.addWidget(self.iptEdt2, 3, 1) iptGrid.setVerticalSpacing(10) iptV = QVBoxLayout() iptV.addLayout(iptGrid) iptV.addLayout(iptH) iptFrame = QFrame() iptFrame.setAutoFillBackground(True) p6 = iptFrame.palette() p6.setColor(iptFrame.backgroundRole(), QColor(220, 225, 255)) iptFrame.setPalette(p6) iptFrame.setFrameShape(QFrame.StyledPanel) iptFrame.setLayout(iptV) srgGrid = QGridLayout() #srgGrid.setVerticalSpacing(10) srgTitle = Text("Algorithms", (255, 0, 0), 12, "center") self.srgBtn1 = QPushButton("Genetic") self.srgBtn1.clicked.connect(self.run_algorithm) self.srgBtn2 = QPushButton("Simulated") self.srgBtn2.clicked.connect(self.run_algorithm) self.srgBtn3 = QPushButton("Tabu") self.srgBtn3.clicked.connect(self.run_algorithm) self.srgBtn4 = QPushButton("reset") self.srgBtn4.clicked.connect(self.reset) srgGrid.addWidget(srgTitle, 1, 0, 1, 6) srgGrid.addWidget(self.srgBtn1, 2, 1, 2, 4) srgGrid.addWidget(self.srgBtn2, 3, 1, 3, 4) srgGrid.addWidget(self.srgBtn3, 4, 1, 4, 4) srgGrid.addWidget(self.srgBtn4, 5, 1, 5, 4) srgFrame = QFrame() srgFrame.setFrameShape(QFrame.StyledPanel) srgFrame.setAutoFillBackground(True) p7 = srgFrame.palette() p7.setColor(srgFrame.backgroundRole(), QColor(255, 255, 255)) srgFrame.setPalette(p7) srgFrame.setLayout(srgGrid) otpGrid = QGridLayout() otpTitle = Text("Program Output", (255, 0, 0), 12, "center") otpTxt1 = QLabel("The Cost") otpTxt1.setFont(QFont("Decorative", 12)) self.lcd1 = QLCDNumber() otpGrid.addWidget(otpTitle, 1, 0, 1, 2) otpGrid.addWidget(otpTxt1, 2, 0) otpGrid.addWidget(self.lcd1, 2, 1) otpFrame = QFrame() otpFrame.setFrameShape(QFrame.StyledPanel) otpFrame.setAutoFillBackground(True) p8 = otpFrame.palette() p8.setColor(otpFrame.backgroundRole(), QColor(220, 225, 255)) otpFrame.setPalette(p8) otpFrame.setLayout(otpGrid) splitter1 = QSplitter(Qt.Vertical) splitter1.addWidget(titleFrame) splitter1.addWidget(iptFrame) splitter1.setSizes([240, 135]) splitter2 = QSplitter(Qt.Vertical) splitter2.addWidget(srgFrame) splitter2.addWidget(otpFrame) splitter2.setSizes([200, 92]) splitter3 = QSplitter(Qt.Vertical) splitter3.addWidget(splitter1) splitter3.addWidget(splitter2) splitter3.setSizes([382, 291]) splitter3.resize(260, 685) splitter3.move(1100, 5) splitter3.setParent(self) splitter3.setAutoFillBackground(True) p3 = splitter3.palette() p3.setColor(splitter3.backgroundRole(), QColor(255, 255, 255)) splitter3.setPalette(p3) self.mapFrame = QFrame() self.mapFrame.setFrameShape(QFrame.StyledPanel) self.mapFrame.move(5, 5) self.mapFrame.resize(1090, 685) self.mapFrame.setParent(self) self.setAutoFillBackground(True) p2 = self.palette() p2.setColor(self.backgroundRole(), QColor(0, 0, 0)) self.setPalette(p2) self.mapFrame.setParent(self) self.hint = Text("Click the bulid button to bulid a random map", (255, 0, 0), 23, "center") self.hint.move(230, 100) self.hint.setParent(self) self.setWindowTitle("TSP") self.width = QDesktopWidget().availableGeometry().width() self.height = QDesktopWidget().availableGeometry().height() - 40 self.resize(self.width, self.height) self.show() self.nodes = {} self.points = {} self.flag = True
class GuiTourneyPlayerStats(QSplitter): def __init__(self, config, db, sql, mainwin, debug=True): QSplitter.__init__(self, mainwin) self.conf = config self.db = db self.cursor = self.db.cursor self.sql = sql self.main_window = mainwin self.debug = debug self.liststore = [ ] # QStandardItemModel[] stores the contents of the grids self.listcols = [] filters_display = { "Heroes": True, "Sites": True, #"Games" : True, #"Limits" : True, #"LimitSep" : True, #"LimitType" : True, #"Type" : True, "Seats": True, #"SeatSep" : True, "Dates": True, #"Groups" : True, #"GroupsAll" : True, #"Button1" : True, "Button2": True } self.stats_frame = None self.stats_vbox = None self.detailFilters = [] # the data used to enhance the sql select self.filters = Filters.Filters(self.db, display=filters_display) #self.filters.registerButton1Name(_("_Filters")) #self.filters.registerButton1Callback(self.showDetailFilter) self.filters.registerButton2Name(_("_Refresh Stats")) self.filters.registerButton2Callback(self.refreshStats) scroll = QScrollArea() scroll.setWidget(self.filters) # ToDo: store in config # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed, column heading, xalignment, formatting, celltype self.columns = [ ["siteName", True, _("Site"), 0.0, "%s", "str"] #,["tourney", False, _("Tourney"), 0.0, "%s", "str"] # true not allowed for this line , ["category", True, _("Cat."), 0.0, "%s", "str"], ["limitType", True, _("Limit"), 0.0, "%s", "str"], ["currency", True, _("Curr."), 0.0, "%s", "str"], ["buyIn", True, _("BuyIn"), 1.0, "%3.2f", "str"], ["fee", True, _("Fee"), 1.0, "%3.2f", "str"], ["playerName", False, _("Name"), 0.0, "%s", "str"] # true not allowed for this line (set in code) , ["tourneyCount", True, _("#"), 1.0, "%1.0f", "str"], ["itm", True, _("ITM%"), 1.0, "%3.2f", "str"], ["_1st", False, _("1st"), 1.0, "%1.0f", "str"], ["_2nd", True, _("2nd"), 1.0, "%1.0f", "str"], ["_3rd", True, _("3rd"), 1.0, "%1.0f", "str"], ["unknownRank", True, _("Rank?"), 1.0, "%1.0f", "str"], ["spent", True, _("Spent"), 1.0, "%3.2f", "str"], ["won", True, _("Won"), 1.0, "%3.2f", "str"], ["roi", True, _("ROI%"), 1.0, "%3.0f", "str"], ["profitPerTourney", True, _("$/Tour"), 1.0, "%3.2f", "str"] ] self.stats_frame = QFrame() self.stats_frame.setLayout(QVBoxLayout()) self.stats_vbox = QSplitter(Qt.Vertical) self.stats_frame.layout().addWidget(self.stats_vbox) # self.fillStatsFrame(self.stats_vbox) #self.main_hbox.pack_start(self.filters.get_vbox()) #self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True) self.addWidget(scroll) self.addWidget(self.stats_frame) self.setStretchFactor(0, 0) self.setStretchFactor(1, 1) def addGrid(self, vbox, query, numTourneys, tourneyTypes, playerids, sitenos, seats): sqlrow = 0 grid = numTourneys #TODO: should this be numTourneyTypes? query = self.sql.query[query] query = self.refineQuery(query, numTourneys, tourneyTypes, playerids, sitenos, seats) self.cursor.execute(query) result = self.cursor.fetchall() colnames = [desc[0] for desc in self.cursor.description] # pre-fetch some constant values: #self.cols_to_show = [x for x in self.columns if x[colshow]] #htourneytypeid_idx = colnames.index('tourneyTypeId') self.cols_to_show = self.columns #TODO do i need above 2 lines? assert len(self.liststore) == grid, "len(self.liststore)=" + str( len(self.liststore)) + " grid-1=" + str(grid) view = QTableView() self.liststore.append( QStandardItemModel(0, len(self.cols_to_show), view)) view.setModel(self.liststore[grid]) view.verticalHeader().hide() vbox.addWidget(view) assert len(self.listcols) == grid self.listcols.append([]) # Create header row eg column: ("game", True, "Game", 0.0, "%s") for col, column in enumerate(self.cols_to_show): if column[colalias] == 'game' and holecards: s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading] else: s = column[colheading] self.listcols[grid].append(s) self.liststore[grid].setHorizontalHeaderLabels(self.listcols[grid]) rows = len(result) # +1 for title row while sqlrow < rows: treerow = [] for col, column in enumerate(self.cols_to_show): if column[colalias] in colnames: value = result[sqlrow][colnames.index(column[colalias])] else: value = 111 if column[colalias] == 'siteName': if result[sqlrow][colnames.index('speed')] != 'Normal': if (result[sqlrow][colnames.index('speed')] == 'Hyper' and result[sqlrow][colnames.index('siteName')] == 'Full Tilt Poker'): value = value + ' ' + 'Super Turbo' else: value = value + ' ' + result[sqlrow][ colnames.index('speed')] item = QStandardItem('') if value != None and value != -999: item = QStandardItem(column[colformat] % value) item.setEditable(False) item.setTextAlignment(Qt.AlignRight) treerow.append(item) self.liststore[grid].appendRow(treerow) sqlrow += 1 view.resizeColumnsToContents() view.setSortingEnabled(True) def createStatsTable(self, vbox, tourneyTypes, playerids, sitenos, seats): startTime = time() numTourneys = self.filters.getNumTourneys() self.addGrid(vbox, 'tourneyPlayerDetailedStats', numTourneys, tourneyTypes, playerids, sitenos, seats) print _("Stats page displayed in %4.2f seconds") % (time() - startTime) def fillStatsFrame(self, vbox): tourneyTypes = self.filters.getTourneyTypes() #tourneys = self.tourneys.getTourneys() sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() seats = self.filters.getSeats() dates = self.filters.getDates() sitenos = [] playerids = [] # Which sites are selected? for site in sites: sitenos.append(siteids[site]) _hname = Charset.to_utf8(heroes[site]) result = self.db.get_player_id(self.conf, site, _hname) if result is not None: playerids.append(int(result)) if not sitenos: #Should probably pop up here. print _("No sites selected - defaulting to PokerStars") sitenos = [2] if not playerids: print _("No player ids found") return self.createStatsTable(vbox, tourneyTypes, playerids, sitenos, seats) def refineQuery(self, query, numTourneys, tourneyTypes, playerids, sitenos, seats): having = '' #print "start of refinequery, playerids:",playerids if playerids: nametest = str(tuple(playerids)) nametest = nametest.replace("L", "") nametest = nametest.replace(",)", ")") else: nametest = "1 = 2" #print "refinequery, nametest after initial creation:",nametest pname = "p.name" # set flag in self.columns to not show player name column #[x for x in self.columns if x[0] == 'pname'][0][1] = False #TODO: fix and reactivate query = query.replace("<nametest>", nametest) query = query.replace("<playerName>", pname) query = query.replace("<havingclause>", having) sitetest = "" q = [] for m in self.filters.display.items(): if m[0] == 'Sites' and m[1]: for n in sitenos: q.append(n) if len(q) > 0: sitetest = str(tuple(q)) sitetest = sitetest.replace("L", "") sitetest = sitetest.replace(",)", ")") sitetest = sitetest.replace("u'", "'") sitetest = "and tt.siteId in %s" % sitetest #[1:-1] else: sitetest = "and tt.siteId IS NULL" #print "refinequery, sitetest before its use for replacement:",sitetest query = query.replace("<sitetest>", sitetest) if seats: query = query.replace( '<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to'])) if False: #'show' in seats and seats['show']: should be 'show' in groups but we don't even display the groups filter query = query.replace('<groupbyseats>', ',h.seats') query = query.replace('<orderbyseats>', ',h.seats') else: query = query.replace('<groupbyseats>', '') query = query.replace('<orderbyseats>', '') else: query = query.replace('<seats_test>', 'between 0 and 100') query = query.replace('<groupbyseats>', '') query = query.replace('<orderbyseats>', '') #bbtest = self.filters.get_limits_where_clause(limits) #query = query.replace("<gtbigBlind_test>", bbtest) #query = query.replace("<orderbyhgametypeId>", "") # process self.detailFilters (a list of tuples) flagtest = '' #self.detailFilters = [('h.seats', 5, 6)] # for debug if self.detailFilters: for f in self.detailFilters: if len(f) == 3: # X between Y and Z flagtest += ' and %s between %s and %s ' % (f[0], str( f[1]), str(f[2])) query = query.replace("<flagtest>", flagtest) # allow for differences in sql cast() function: if self.db.backend == self.db.MYSQL_INNODB: query = query.replace("<signed>", 'signed ') else: query = query.replace("<signed>", '') # Filter on dates start_date, end_date = self.filters.getDates() query = query.replace("<startdate_test>", start_date) query = query.replace("<enddate_test>", end_date) return (query) def refreshStats(self, widget): # self.last_pos = self.stats_vbox.get_position() self.stats_frame.layout().removeWidget(self.stats_vbox) self.stats_vbox.setParent(None) self.liststore = [] self.listcols = [] #self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox = QSplitter(Qt.Vertical) self.stats_frame.layout().addWidget(self.stats_vbox) self.fillStatsFrame(self.stats_vbox) # if self.last_pos > 0: # self.stats_vbox.set_position(self.last_pos) def reset_style_render_func(self, treeviewcolumn, cell, model, iter): cell.set_property('foreground', None) def sortCols(self, col, nums): #This doesn't actually work yet - clicking heading in top section sorts bottom section :-( (n, grid) = nums if not col.get_sort_indicator() or col.get_sort_order( ) == gtk.SORT_ASCENDING: col.set_sort_order(gtk.SORT_DESCENDING) else: col.set_sort_order(gtk.SORT_ASCENDING) self.liststore[grid].set_sort_column_id(n, col.get_sort_order()) self.liststore[grid].set_sort_func(n, self.sortnums, (n, grid)) for i in xrange(len(self.listcols[grid])): self.listcols[grid][i].set_sort_indicator(False) self.listcols[grid][n].set_sort_indicator(True)