summaryrefslogtreecommitdiff
path: root/jfr_playoff/gui
diff options
context:
space:
mode:
authoremkael <emkael@tlen.pl>2019-07-22 11:39:02 +0200
committeremkael <emkael@tlen.pl>2019-07-22 11:39:02 +0200
commit8bf96412b75689c578f5690dd0974304265d7fea (patch)
tree00927af4c406028b437a1890840ea7168267f1f9 /jfr_playoff/gui
parent37a2b34d2dd68092196e391b8ccc08c092f9912a (diff)
Collecting and saving config file
Diffstat (limited to 'jfr_playoff/gui')
-rw-r--r--jfr_playoff/gui/__init__.py30
-rw-r--r--jfr_playoff/gui/frames/match.py98
-rw-r--r--jfr_playoff/gui/frames/network.py12
-rw-r--r--jfr_playoff/gui/frames/translations.py8
-rw-r--r--jfr_playoff/gui/frames/visual.py55
-rw-r--r--jfr_playoff/gui/tabs.py62
6 files changed, 262 insertions, 3 deletions
diff --git a/jfr_playoff/gui/__init__.py b/jfr_playoff/gui/__init__.py
index 59821cb..551aec2 100644
--- a/jfr_playoff/gui/__init__.py
+++ b/jfr_playoff/gui/__init__.py
@@ -1,6 +1,6 @@
#coding=utf-8
-import json, os, sys
+import codecs, copy, json, os, sys
import tkinter as tk
from tkinter import ttk
@@ -122,7 +122,33 @@ class PlayoffGUI(tk.Tk):
self.after(0, self._dirty.set, False)
def saveFile(self, filepath):
- pass
+ json.dump(
+ self.getConfig(), codecs.open(filepath, 'w', encoding='utf8'),
+ indent=4, ensure_ascii=False)
+ self._filepath = filepath
+ self._title.set(os.path.basename(filepath))
+ self.after(0, self._dirty.set, False)
+
+ def getConfig(self):
+ config = {} # TODO: OrderderDict, everywhere
+ for tab in self.tabs.values():
+ tabConfig = tab.getConfig()
+ if tabConfig is not None:
+ config = self._mergeConfig(config, tab.getConfig())
+ return config
+
+ def _mergeConfig(self, base, update):
+ result = copy.copy(base)
+ for key, value in update.iteritems():
+ if key in result:
+ if isinstance(result[key], dict):
+ result[key] = self._mergeConfig(
+ result[key], update[key])
+ else:
+ result[key] = update[key]
+ else:
+ result[key] = value
+ return result
def getDbConfig(self):
return self.tabs['NetworkTab'].getDB()
diff --git a/jfr_playoff/gui/frames/match.py b/jfr_playoff/gui/frames/match.py
index 685d399..ad22a3b 100644
--- a/jfr_playoff/gui/frames/match.py
+++ b/jfr_playoff/gui/frames/match.py
@@ -170,6 +170,22 @@ class SwissSettingsFrame(RepeatableFrame):
self.linkRelPath.set(
value['relative_path'] if 'relative_path' in value else '')
+ def getValue(self):
+ config = {}
+ if self.source.get() == self.SOURCE_DB:
+ config['database'] = self.fetchDB.get()
+ if self.linkRelPath.get():
+ config['relative_path'] = self.linkRelPath.get()
+ if self.source.get() == self.SOURCE_LINK:
+ config['link'] = self.fetchLink.get()
+ if self.linkLabel.get():
+ config['label'] = self.linkLabel.get()
+ config['position'] = self.setFrom.get()
+ if self.setToEnabled.get():
+ config['position_to'] = self.setTo.get()
+ if self.fetchFromEnabled.get():
+ config['swiss_position'] = self.fetchFrom.get()
+ return config
class SwissesFrame(ScrollableFrame):
def renderContent(self, container):
@@ -179,6 +195,9 @@ class SwissesFrame(ScrollableFrame):
def setValues(self, values):
self.swisses.setValue(values)
+ def getValues(self):
+ return self.swisses.getValue()
+
class MatchSelectionButton(SelectionButton):
@property
def defaultPrompt(self):
@@ -390,6 +409,16 @@ class BracketMatchSettingsFrame(GuiFrame):
self.selectedIndex.set(('none', ''))
self.selected.set(0)
+ def getSelectedTeam(self):
+ if self.selected.get():
+ try:
+ return self.bracketWidgets[7].getValues().index(
+ self.selectedIndex.get())
+ except ValueError:
+ return -1
+ else:
+ return -1
+
def getConfig(self):
if self.source.get() == self.SOURCE_TEAM:
return self.teams
@@ -406,6 +435,9 @@ class BracketMatchSettingsFrame(GuiFrame):
config[key] = values
return config
+ def getValue(self):
+ return self.getConfig()
+
class MatchSettingsFrame(RepeatableFrame):
SCORE_SOURCE_DB = 0
SCORE_SOURCE_LINK = 1
@@ -665,6 +697,53 @@ class MatchSettingsFrame(RepeatableFrame):
for idx in range(0, 2):
self.bracketSettings[idx].setSelectedTeam(-1)
+ def getValue(self):
+ config = {}
+ config['id'] = self.matchID.get()
+ if self.link.get():
+ config['link'] = self.link.get()
+
+ config['teams'] = [bracket.getValue()
+ for bracket in self.bracketSettings]
+
+ if len(self.winnerPositions):
+ config['winner'] = self.winnerPositions
+ if len(self.loserPositions):
+ config['loser'] = self.loserPositions
+
+ selected = [bracket.getSelectedTeam()
+ for bracket in self.bracketSettings]
+ if len([s for s in selected if s > -1]):
+ config['selected_teams'] = selected
+
+ if self.source.get() == self.SCORE_SOURCE_DB:
+ config['database'] = self.scoreDB.get()
+ config['round'] = self.scoreRound.get()
+ if self.source.get() != self.SCORE_SOURCE_CUSTOM:
+ config['table'] = self.scoreTable.get()
+
+ if self.source.get() == self.SCORE_SOURCE_CUSTOM:
+ config['score'] = []
+ for score in self.scoreCustom:
+ try:
+ config['score'].append(float(score.get()))
+ except ValueError:
+ config['score'].append(0.0)
+ if self.scoreNotFinished.get():
+ config['running'] = self.scoreBoards.get()
+
+ return config
+
+ if 'selected_teams' in value \
+ and isinstance(value['selected_teams'], list):
+ for idx, val in enumerate(value['selected_teams']):
+ if idx < 2:
+ self.bracketSettings[idx].setSelectedTeam(val)
+ else:
+ for idx in range(0, 2):
+ self.bracketSettings[idx].setSelectedTeam(-1)
+
+
class MatchSeparator(RepeatableFrame):
def renderContent(self):
@@ -725,5 +804,24 @@ class MatchPhaseFrame(ScrollableFrame):
self.winfo_toplevel().event_generate(
'<<MatchListChanged>>', when='tail')
+ def getConfig(self):
+ config = {}
+ if self.name.get():
+ config['title'] = self.name.get()
+ if self.link.get():
+ config['link'] = self.link.get()
+ values = self.matches.getValue()
+ dummies = []
+ matches = []
+ for idx, value in enumerate(values):
+ if value is None:
+ dummies.append(idx)
+ else:
+ matches.append(value)
+ if len(dummies):
+ config['dummies'] = dummies
+ config['matches'] = matches
+ return config
+
__all__ = ['SwissesFrame', 'MatchPhaseFrame', 'MatchSettingsFrame']
diff --git a/jfr_playoff/gui/frames/network.py b/jfr_playoff/gui/frames/network.py
index d44ff49..fc00575 100644
--- a/jfr_playoff/gui/frames/network.py
+++ b/jfr_playoff/gui/frames/network.py
@@ -166,6 +166,15 @@ class GoniecConfigurationFrame(GuiFrame):
values['port'] if 'port' in values else self.DEFAULT_PORT)
self.enable.set(values['enabled'] if 'enabled' in values else 0)
+ def getValues(self):
+ config = {
+ 'enabled': self.enable.get()
+ }
+ if self.enable.get():
+ config['host'] = self.host.get()
+ config['port'] = self.port.get()
+ return config
+
class RemoteConfigurationFrame(ScrollableFrame):
def renderContent(self, container):
frame = ttk.LabelFrame(container, text='Zdalne pliki konfiguracyjne:')
@@ -178,4 +187,7 @@ class RemoteConfigurationFrame(ScrollableFrame):
def setValues(self, values):
self.repeater.setValue(values)
+ def getValues(self):
+ return self.repeater.getValue()
+
__all__ = ['MySQLConfigurationFrame', 'GoniecConfigurationFrame', 'RemoteConfigurationFrame']
diff --git a/jfr_playoff/gui/frames/translations.py b/jfr_playoff/gui/frames/translations.py
index 3ba660f..e5b8940 100644
--- a/jfr_playoff/gui/frames/translations.py
+++ b/jfr_playoff/gui/frames/translations.py
@@ -23,6 +23,9 @@ class TranslationRow(RepeatableFrame):
self.key.set(value[0])
self.value.set(value[1])
+ def getValue(self):
+ return (self.key.get(), self.value.get())
+
class TranslationConfigurationFrame(ScrollableFrame):
def setTranslations(self, translations):
@@ -33,6 +36,11 @@ class TranslationConfigurationFrame(ScrollableFrame):
values.append(value)
self.repeater.setValue(values)
+ def getTranslations(self):
+ return {
+ key: value for key, value in self.repeater.getValue()
+ }
+
def renderContent(self, container):
self.repeater = WidgetRepeater(container, TranslationRow)
self.repeater.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
diff --git a/jfr_playoff/gui/frames/visual.py b/jfr_playoff/gui/frames/visual.py
index 6780e99..9bbe5f6 100644
--- a/jfr_playoff/gui/frames/visual.py
+++ b/jfr_playoff/gui/frames/visual.py
@@ -178,6 +178,25 @@ class VisualSettingsFrame(GuiFrame):
self.teamNameSeparator.set(values['team_boxes']['name_separator'])
self.teamNamePrefix.set(values['team_boxes']['name_prefix'])
+ def getValues(self):
+ return {
+ 'width': self.boxWidth.get(default=250),
+ 'height': self.boxHeight.get(default=80),
+ 'margin': self.boxMargin.get(default=60),
+ 'starting_position_indicators': self.startingPositionIndicators.get(),
+ 'finishing_position_indicators': self.finishingPositionIndicators.get(),
+ 'team_boxes': {
+ 'label_length_limit': self.teamNameLength.get(default=25) if self.shortenTeamNames else 0,
+ 'predict_teams': self.teamNamePredict.get(),
+ 'label_separator': self.teamLabelSeparator.get(),
+ 'label_placeholder': self.teamNamePlaceholder.get(),
+ 'label_ellipsis': self.teamNameEllipsis.get(),
+ 'name_separator': self.teamNameSeparator.get(),
+ 'name_prefix': self.teamNamePrefix.get(),
+ 'sort_eligible_first': self.teamNameSortPredictions.get()
+ }
+ }
+
class MatchList(RefreshableOptionMenu):
def __init__(self, *args, **kwargs):
@@ -235,6 +254,13 @@ class BoxPositionFrame(RepeatableFrame):
self.vertical.set(0)
self.horizontal.set(-1)
+ def getValue(self):
+ horizontal = self.horizontal.get(default=-1)
+ vertical = self.vertical.get(default=0)
+ return (
+ self.match.get(),
+ [vertical, horizontal] if horizontal >= 0 else vertical)
+
class BoxPositionsFrame(ScrollableFrame):
def renderContent(self, container):
(ttk.Label(container, text='Pozycje tabelek meczów:')).pack(
@@ -255,6 +281,9 @@ class BoxPositionsFrame(ScrollableFrame):
values_to_set.append(value)
self.positions.setValue(values_to_set)
+ def getValues(self):
+ return { match: config for match, config in self.positions.getValue() }
+
class LineStyle(GuiFrame):
def _selectColour(self):
colour = tkcc.askcolor(self._getColour())
@@ -288,6 +317,9 @@ class LineStyle(GuiFrame):
self.hOffset.set(value[1])
self.vOffset.set(value[2])
+ def getValue(self):
+ return [self._getColour(), self.hOffset.get(), self.vOffset.get()]
+
class LineStylesFrame(GuiFrame):
DEFAULT_VALUES = [
('winner', ('#00ff00', 5, -10),
@@ -303,6 +335,7 @@ class LineStylesFrame(GuiFrame):
('finish_loser', ('#ff0000', 20, 10),
'Przegrani meczów kończący rozgrywki: ')
]
+ CONFIG_KEYS = ['colour', 'h_offset', 'v_offset']
def renderContent(self):
self.lines = {}
@@ -317,12 +350,20 @@ class LineStylesFrame(GuiFrame):
def setValues(self, values):
for line in self.DEFAULT_VALUES:
value = list(line[1])
- for idx, key in enumerate(['colour', 'h_offset', 'v_offset']):
+ for idx, key in enumerate(self.CONFIG_KEYS):
key = '%s_%s' % (line[0], key)
if key in values:
value[idx] = values[key]
self.lines[line[0]].setValue(value)
+ def getValues(self):
+ config = {}
+ for line, widget in self.lines.iteritems():
+ value = widget.getValue()
+ for idx, key in enumerate(self.CONFIG_KEYS):
+ config['%s_%s' % (line, key)] = value[idx]
+ return config
+
class PositionsSelectionFrame(SelectionFrame):
COLUMN_COUNT=10
@@ -381,6 +422,15 @@ class PositionStyleFrame(RepeatableFrame):
value['positions'] if 'positions' in value else [])
self.description.set(value['caption'] if 'caption' in value else '')
+ def getValue(self):
+ config = {
+ 'class': self.name.get(),
+ 'positions': self.positions
+ }
+ caption = self.description.get()
+ if caption:
+ config['caption'] = caption
+ return config
class PositionStylesFrame(ScrollableFrame):
def renderContent(self, container):
@@ -392,4 +442,7 @@ class PositionStylesFrame(ScrollableFrame):
def setValues(self, values):
self.styles.setValue(values)
+ def getValues(self):
+ return self.styles.getValue()
+
__all__ = ['VisualSettingsFrame', 'BoxPositionsFrame', 'LineStylesFrame', 'PositionStylesFrame']
diff --git a/jfr_playoff/gui/tabs.py b/jfr_playoff/gui/tabs.py
index 8b66b25..2b316f4 100644
--- a/jfr_playoff/gui/tabs.py
+++ b/jfr_playoff/gui/tabs.py
@@ -39,6 +39,9 @@ class PlayoffTab(ttk.Frame):
def setValues(self, config):
pass
+ def getConfig(self):
+ pass
+
class MainSettingsTab(PlayoffTab):
DEFAULT_INTERVAL = 60
@@ -145,6 +148,17 @@ class MainSettingsTab(PlayoffTab):
container.columnconfigure(1, weight=1)
container.rowconfigure(4, weight=1)
+ def getConfig(self):
+ return {
+ 'output': self.outputPath.get(),
+ 'page': {
+ 'title': self.pageTitle.get(),
+ 'logoh': self.pageLogoh.get(),
+ 'refresh': self.refreshInterval.get() \
+ if self.refresh.get() > 0 else 0
+ }
+ }
+
class TeamsTab(PlayoffTab):
@property
def title(self):
@@ -218,6 +232,9 @@ class TeamsTab(PlayoffTab):
config['teams']['ties']
if 'teams' in config and 'ties' in config['teams'] else [])
+ def getConfig(self):
+ return self.collectConfig()
+
class MatchesTab(PlayoffTab):
@property
def title(self):
@@ -294,6 +311,11 @@ class MatchesTab(PlayoffTab):
match.matchID.set(
self.winfo_toplevel().getNewMatchID(match))
+ def getConfig(self):
+ return {
+ 'phases': [phase.getConfig() for phase in self.phases.values()]
+ }
+
class SwissesTab(PlayoffTab):
@property
def title(self):
@@ -306,6 +328,15 @@ class SwissesTab(PlayoffTab):
def setValues(self, config):
self.swisses.setValues(config['swiss'] if 'swiss' in config else [])
+ def getConfig(self):
+ swisses = self.swisses.getValues()
+ if len(swisses):
+ return {
+ 'swiss': swisses
+ }
+ else:
+ return None
+
class NetworkTab(PlayoffTab):
@property
def title(self):
@@ -362,6 +393,16 @@ class NetworkTab(PlayoffTab):
self.remoteFrame.setValues(
config['remotes'] if 'remotes' in config else [])
+ def getConfig(self):
+ config = {}
+ mysql = self.getDB()
+ if mysql is not None:
+ config['database'] = mysql
+ config['goniec'] = self.goniecFrame.getValues()
+ remotes = self.remoteFrame.getValues()
+ if len(remotes):
+ config['remotes'] = remotes
+ return config
class VisualTab(PlayoffTab):
@property
@@ -388,6 +429,16 @@ class VisualTab(PlayoffTab):
else:
self.positionFrame.setValues({})
+ def getConfig(self):
+ config = {
+ 'page': self.settingsFrame.getValues()
+ }
+ boxConfig = self.positionFrame.getValues()
+ if boxConfig:
+ config['canvas'] = {}
+ config['canvas']['box_positioning'] = boxConfig
+ return config
+
class StyleTab(PlayoffTab):
@property
def title(self):
@@ -414,6 +465,12 @@ class StyleTab(PlayoffTab):
else:
self.positionStylesFrame.setValues([])
+ def getConfig(self):
+ return {
+ 'canvas': self.linesFrame.getValues(),
+ 'position_styles': self.positionStylesFrame.getValues()
+ }
+
class TranslationsTab(PlayoffTab):
@property
def title(self):
@@ -430,5 +487,10 @@ class TranslationsTab(PlayoffTab):
else:
self.translationsFrame.setTranslations({})
+ def getConfig(self):
+ return {
+ 'i18n': self.translationsFrame.getTranslations()
+ }
+
__all__ = ['MainSettingsTab', 'TeamsTab', 'MatchesTab', 'SwissesTab',
'NetworkTab', 'VisualTab', 'StyleTab', 'TranslationsTab']