bugfix
This commit is contained in:
parent
27b5057d33
commit
4e8e183307
@ -1,5 +1,6 @@
|
|||||||
from appPublic.timeUtils import curDateString, monthMaxDay
|
from appPublic.timeUtils import curDateString, monthMaxDay
|
||||||
|
|
||||||
|
from kivy.clock import Clock
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
from kivy.properties import NumericProperty
|
from kivy.properties import NumericProperty
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
@ -16,6 +17,8 @@ class YearInput(SelectInput):
|
|||||||
self.showed_max = None
|
self.showed_max = None
|
||||||
self.valueField = self.dropdown.valueField
|
self.valueField = self.dropdown.valueField
|
||||||
self.textField = self.dropdown.textField
|
self.textField = self.dropdown.textField
|
||||||
|
self.reopen = False
|
||||||
|
self.dropdown.bind(on_dismiss=self.reopen_dropdown)
|
||||||
|
|
||||||
def e_year_change(self, y):
|
def e_year_change(self, y):
|
||||||
self.e_year = y
|
self.e_year = y
|
||||||
@ -44,6 +47,11 @@ class YearInput(SelectInput):
|
|||||||
})
|
})
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def reopen_dropdown(self, *args):
|
||||||
|
if not self.reopen:
|
||||||
|
return
|
||||||
|
self.dropdown.open(self)
|
||||||
|
|
||||||
def dropdown_select(self, o, d):
|
def dropdown_select(self, o, d):
|
||||||
if d[0] == -10000:
|
if d[0] == -10000:
|
||||||
smin = self.showed_min - self.show_years
|
smin = self.showed_min - self.show_years
|
||||||
@ -51,6 +59,7 @@ class YearInput(SelectInput):
|
|||||||
smin = 0
|
smin = 0
|
||||||
smax = smin + self.show_years
|
smax = smin + self.show_years
|
||||||
self.set_selectable_data(self.years_data(smin, smax))
|
self.set_selectable_data(self.years_data(smin, smax))
|
||||||
|
self.reopen = True
|
||||||
return
|
return
|
||||||
if d[0] == 10000:
|
if d[0] == 10000:
|
||||||
smax = self.showed_max + self.show_years
|
smax = self.showed_max + self.show_years
|
||||||
@ -58,9 +67,10 @@ class YearInput(SelectInput):
|
|||||||
smax = 9999
|
smax = 9999
|
||||||
smin = smax - self.show_years
|
smin = smax - self.show_years
|
||||||
self.set_selectable_data(self.years_data(smin, smax))
|
self.set_selectable_data(self.years_data(smin, smax))
|
||||||
self.dropdown.open()
|
self.reopen = True
|
||||||
return
|
return
|
||||||
super().dropdown_select(o,d)
|
super().dropdown_select(o,d)
|
||||||
|
self.reopen = False
|
||||||
|
|
||||||
def setValue(self, v):
|
def setValue(self, v):
|
||||||
super().setValue(v)
|
super().setValue(v)
|
||||||
@ -69,17 +79,14 @@ class YearInput(SelectInput):
|
|||||||
class DateInput(HBox):
|
class DateInput(HBox):
|
||||||
def __init__(self, allow_copy=True, **kw):
|
def __init__(self, allow_copy=True, **kw):
|
||||||
print('DateInput():kw=', kw)
|
print('DateInput():kw=', kw)
|
||||||
kw['size_hint_y'] = None
|
self.datetype = 'yyyy-mm-dd'
|
||||||
kw['height'] = CSize(3)
|
|
||||||
kw['size_hint_x'] = None
|
kw['size_hint_x'] = None
|
||||||
kw['width'] = 10
|
kw['width'] = 10
|
||||||
super(DateInput, self).__init__(**kw)
|
super(DateInput, self).__init__(**kw)
|
||||||
self.register_event_type('on_changed')
|
self.register_event_type('on_changed')
|
||||||
self.old_datestr = None
|
self.old_datestr = None
|
||||||
value = kw.get('value',kw.get('defautvalue',curDateString()))
|
value = kw.get('value',kw.get('defautvalue',curDateString()))
|
||||||
y = int(value[:4])
|
y, m, d = self.str2ymd(value)
|
||||||
m = int(value[5:7])
|
|
||||||
d = int(value[9:10])
|
|
||||||
months_data = []
|
months_data = []
|
||||||
days_data = []
|
days_data = []
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
@ -96,7 +103,7 @@ class DateInput(HBox):
|
|||||||
})
|
})
|
||||||
self.days_data = days_data
|
self.days_data = days_data
|
||||||
self.yw = YearInput(data=[],
|
self.yw = YearInput(data=[],
|
||||||
size_hint_x=None, width=4)
|
size_hint_x=None, width=3.6)
|
||||||
self.mw = SelectInput(size_hint_x=None, width=2,
|
self.mw = SelectInput(size_hint_x=None, width=2,
|
||||||
data=months_data)
|
data=months_data)
|
||||||
self.dw = SelectInput( size_hint_x=None, width=2,
|
self.dw = SelectInput( size_hint_x=None, width=2,
|
||||||
@ -114,6 +121,32 @@ class DateInput(HBox):
|
|||||||
self.yw.bind(on_changed=self.data_changed)
|
self.yw.bind(on_changed=self.data_changed)
|
||||||
self.mw.bind(on_changed=self.data_changed)
|
self.mw.bind(on_changed=self.data_changed)
|
||||||
self.dw.bind(on_changed=self.data_changed)
|
self.dw.bind(on_changed=self.data_changed)
|
||||||
|
self.on_size()
|
||||||
|
|
||||||
|
def on_size(self, *args):
|
||||||
|
if not hasattr(self, 'yw'):
|
||||||
|
return
|
||||||
|
self.yw.height = self.height
|
||||||
|
self.mw.height = self.height
|
||||||
|
self.dw.height = self.height
|
||||||
|
|
||||||
|
def str2ymd(self, datestr):
|
||||||
|
if len(datestr) == 8:
|
||||||
|
self.datetype = 'yyyymmdd'
|
||||||
|
y = int(datestr[:4])
|
||||||
|
m = int(datestr[4:6])
|
||||||
|
d = int(datestr[6:8])
|
||||||
|
return y, m, d
|
||||||
|
self.datetype = 'yyyy-mm-dd'
|
||||||
|
y = int(datestr[:4])
|
||||||
|
m = int(datestr[5:7])
|
||||||
|
d = int(datestr[9:10])
|
||||||
|
return y, m, d
|
||||||
|
|
||||||
|
def ymd2str(self, y, m, d):
|
||||||
|
if self.datetype == 'yyyymmdd':
|
||||||
|
return '%4d%02d%02d' % (y,m,d)
|
||||||
|
return '%04d-%02d-%02d' % (y, m, d)
|
||||||
|
|
||||||
def data_changed(self, o, d):
|
def data_changed(self, o, d):
|
||||||
y = self.yw.getValue()
|
y = self.yw.getValue()
|
||||||
@ -124,7 +157,7 @@ class DateInput(HBox):
|
|||||||
data = self.days_data[:mdays]
|
data = self.days_data[:mdays]
|
||||||
self.dw.set_selectable_data(data)
|
self.dw.set_selectable_data(data)
|
||||||
if d <= mdays and d>0:
|
if d <= mdays and d>0:
|
||||||
datestr = '%d-%02d-%02d' % (y,m,d)
|
datestr = self.ymd2str(y,m,d)
|
||||||
if self.old_datestr != datestr:
|
if self.old_datestr != datestr:
|
||||||
self.old_datestr = datestr
|
self.old_datestr = datestr
|
||||||
self.dispatch('on_changed', datestr)
|
self.dispatch('on_changed', datestr)
|
||||||
@ -138,14 +171,12 @@ class DateInput(HBox):
|
|||||||
d = self.dw.getValue()
|
d = self.dw.getValue()
|
||||||
mdays = monthMaxDay(y,m)
|
mdays = monthMaxDay(y,m)
|
||||||
if d <= mdays and d>0:
|
if d <= mdays and d>0:
|
||||||
return '%d-%02d-%02d' % (y,m,d)
|
return self.ymd2str(y,m,d)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def setValue(self, datestr):
|
def setValue(self, datestr):
|
||||||
self.old_value = datestr
|
self.old_value = datestr
|
||||||
y = int(datestr[:4])
|
y, m, d = self.str2ymd(datestr)
|
||||||
m = int(datestr[5:7])
|
|
||||||
d = int(datestr[9:10])
|
|
||||||
self.yw.setValue(y)
|
self.yw.setValue(y)
|
||||||
self.mw.setValue(m)
|
self.mw.setValue(m)
|
||||||
self.dw.setValue(d)
|
self.dw.setValue(d)
|
||||||
|
@ -1,189 +0,0 @@
|
|||||||
import traceback
|
|
||||||
|
|
||||||
from kivy.clock import Clock
|
|
||||||
from kivy.factory import Factory
|
|
||||||
from kivy.properties import ListProperty, BooleanProperty, \
|
|
||||||
StringProperty, DictProperty, NumericProperty
|
|
||||||
from kivy.uix.treeview import TreeView, TreeViewNode, TreeViewLabel
|
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
|
||||||
from kivy.uix.image import AsyncImage
|
|
||||||
|
|
||||||
from .threadcall import HttpClient
|
|
||||||
from .scrollpanel import ScrollPanel
|
|
||||||
from .clickable import SingleCheckBox
|
|
||||||
from .baseWidget import Text
|
|
||||||
from .utils import CSize
|
|
||||||
|
|
||||||
class TreeViewComplexNode(BoxLayout, TreeViewLabel):
|
|
||||||
otext = StringProperty(None)
|
|
||||||
checkbox = BooleanProperty(False)
|
|
||||||
icon = StringProperty(None)
|
|
||||||
data = DictProperty(None)
|
|
||||||
def __init__(self, **kw):
|
|
||||||
super(TreeViewComplexNode, self).__init__(**kw)
|
|
||||||
self.orientation = 'horizontal'
|
|
||||||
self.size_hint_x = None
|
|
||||||
if self.checkbox:
|
|
||||||
cb = SingleCheckBox(size_hint=(None,None))
|
|
||||||
cb.bind(on_press=self.set_checked)
|
|
||||||
self.add_widget(cb)
|
|
||||||
if self.icon:
|
|
||||||
img = AsyncImage(source=self.icon, size_hint=(None,None))
|
|
||||||
img.size = CSize(1,1)
|
|
||||||
self.add_widget(img)
|
|
||||||
txt = Text(otext=self.otext, i18n=True)
|
|
||||||
txt.texture_update()
|
|
||||||
txt.size_hint = (None, None)
|
|
||||||
txt.size = txt.texture_size
|
|
||||||
self.add_widget(txt)
|
|
||||||
|
|
||||||
def set_checked(self, o):
|
|
||||||
if not self.data:
|
|
||||||
return
|
|
||||||
if o.state():
|
|
||||||
self.data['checked'] = True
|
|
||||||
else:
|
|
||||||
self.data['checked'] = False
|
|
||||||
|
|
||||||
class Hirarchy(ScrollPanel):
|
|
||||||
url = StringProperty(None)
|
|
||||||
params = DictProperty(None)
|
|
||||||
method = StringProperty('get')
|
|
||||||
idField = StringProperty(None)
|
|
||||||
textField = StringProperty(None)
|
|
||||||
data = ListProperty(None)
|
|
||||||
checkbox = BooleanProperty(False)
|
|
||||||
icon = StringProperty(None)
|
|
||||||
single_expand = BooleanProperty(False)
|
|
||||||
def __init__(self, **kw):
|
|
||||||
self.register_event_type('on_press')
|
|
||||||
self.tree = TreeView(hide_root=True)
|
|
||||||
self.tree.size_hint = (None, None)
|
|
||||||
self.tree.bind(on_node_expand=self.check_load_subnodes)
|
|
||||||
self.tree.bind(selected_node=self.node_selected)
|
|
||||||
super(Hirarchy, self).__init__(inner=self.tree, **kw)
|
|
||||||
if self.url:
|
|
||||||
self.data = self.get_remote_data()
|
|
||||||
|
|
||||||
def on_press(self, node):
|
|
||||||
print('selected node=', node)
|
|
||||||
|
|
||||||
def node_selected(self, o, v):
|
|
||||||
if self.tree.selected_node:
|
|
||||||
self.dispatch('on_press', o.selected_node)
|
|
||||||
|
|
||||||
def collapse_others(self, node):
|
|
||||||
for n in self.tree.iterate_open_nodes(node=node.parent_node):
|
|
||||||
if n != node and n !=node.parent_node and n.is_open:
|
|
||||||
self.tree.toggle_node(n)
|
|
||||||
|
|
||||||
def check_load_subnodes(self, treeview, node):
|
|
||||||
if self.single_expand:
|
|
||||||
self.collapse_others(node)
|
|
||||||
if node.is_loaded:
|
|
||||||
return
|
|
||||||
if not self.url:
|
|
||||||
node.is_loaded = True
|
|
||||||
return
|
|
||||||
data = self.get_remote_data(node)
|
|
||||||
for d in data:
|
|
||||||
self.create_new_node(d, node)
|
|
||||||
node.is_loaded = True
|
|
||||||
|
|
||||||
def create_new_node(self, data, node=None):
|
|
||||||
n = TreeViewComplexNode(otext=data[self.textField],
|
|
||||||
checkbox=self.checkbox,
|
|
||||||
icon=data.get('icon') or self.icon
|
|
||||||
)
|
|
||||||
n.data = data
|
|
||||||
n.width = self.tree.indent_start + \
|
|
||||||
self.tree.indent_level * n.level \
|
|
||||||
+ sum([i.width for i in n.children])
|
|
||||||
if node:
|
|
||||||
self.tree.add_node(n, node)
|
|
||||||
else:
|
|
||||||
self.tree.add_node(n)
|
|
||||||
children = data.get('children')
|
|
||||||
if not children:
|
|
||||||
return
|
|
||||||
for c in children:
|
|
||||||
self.create_new_node(c, n)
|
|
||||||
n.is_loaded = True
|
|
||||||
|
|
||||||
def get_remote_data(self, node=None):
|
|
||||||
if not self.url:
|
|
||||||
return
|
|
||||||
hc = HttpClient()
|
|
||||||
params = self.params.copy() if self.params else {}
|
|
||||||
if node:
|
|
||||||
params['id'] = node.data[self.idField]
|
|
||||||
print('params=', params)
|
|
||||||
d = hc(self.url, method=self.method, params=params)
|
|
||||||
if isinstance(d, list):
|
|
||||||
return d
|
|
||||||
if isinstance(d, dict):
|
|
||||||
return d['rows']
|
|
||||||
return None
|
|
||||||
|
|
||||||
def on_data(self, o, d=None):
|
|
||||||
if not self.data:
|
|
||||||
return
|
|
||||||
for d in self.data:
|
|
||||||
self.create_new_node(d)
|
|
||||||
|
|
||||||
class Menu(Hirarchy):
|
|
||||||
target = StringProperty(None)
|
|
||||||
def __init__(self, **kw):
|
|
||||||
self.target_w = None
|
|
||||||
super(Menu, self).__init__(**kw)
|
|
||||||
|
|
||||||
def on_press(self, node):
|
|
||||||
self.tree.deselect_node()
|
|
||||||
data = {}
|
|
||||||
dw = node.data.get('datawidget')
|
|
||||||
if dw:
|
|
||||||
data_widget = Factory.Blocks.getWidgetById(dw)
|
|
||||||
if data_widget:
|
|
||||||
vn = node.data.get('datamethod', 'getValue')
|
|
||||||
if hasattr(data_widget, vn):
|
|
||||||
f = getattr(data_widget, vn)
|
|
||||||
data = f()
|
|
||||||
if not isinstance(data, dict):
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
url = node.data.get('url')
|
|
||||||
target = Factory.Blocks.getWidgetById(node.data.get('target',self.target),self)
|
|
||||||
if url:
|
|
||||||
params = node.data.get('params',{})
|
|
||||||
params.update(data)
|
|
||||||
blocks = Factory.Blocks()
|
|
||||||
desc = {
|
|
||||||
"widgettype":"urlwidget",
|
|
||||||
"options":{
|
|
||||||
"url":url,
|
|
||||||
"params":params
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w = blocks.widgetBuild(desc)
|
|
||||||
if w and target:
|
|
||||||
target.add_widget(w)
|
|
||||||
return
|
|
||||||
|
|
||||||
rfname = node.data.get('rfname')
|
|
||||||
if rfname:
|
|
||||||
f = getRegisterFunctionByName(rfname)
|
|
||||||
if f:
|
|
||||||
f(self, **data)
|
|
||||||
return
|
|
||||||
|
|
||||||
script = node.data.get('script')
|
|
||||||
if script:
|
|
||||||
target_name = node.data.get('target', self.target)
|
|
||||||
target = Factory.Blocks.getWidgetById(target_name, self)
|
|
||||||
data.update({'self':target})
|
|
||||||
if target:
|
|
||||||
eval(script,data)
|
|
||||||
return
|
|
||||||
|
|
||||||
Factory.register('Hirarchy', Hirarchy)
|
|
||||||
Factory.register('Menu', Menu)
|
|
Loading…
Reference in New Issue
Block a user