diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/docs/blocks.md b/docs/blocks.md old mode 100644 new mode 100755 diff --git a/docs/changelog.md b/docs/changelog.md old mode 100644 new mode 100755 diff --git a/docs/cn/binds.md b/docs/cn/binds.md old mode 100644 new mode 100755 diff --git a/docs/cn/cdf.md b/docs/cn/cdf.md old mode 100644 new mode 100755 diff --git a/docs/cn/index.md b/docs/cn/index.md old mode 100644 new mode 100755 diff --git a/docs/cn/intro.md b/docs/cn/intro.md old mode 100644 new mode 100755 diff --git a/docs/en/box.md b/docs/en/box.md old mode 100644 new mode 100755 diff --git a/docs/imgs/hello_window.png b/docs/imgs/hello_window.png old mode 100644 new mode 100755 diff --git a/github-speed-up.md b/github-speed-up.md old mode 100644 new mode 100755 diff --git a/kivyblocks/__init__.py b/kivyblocks/__init__.py old mode 100644 new mode 100755 diff --git a/kivyblocks/android_rotation.py b/kivyblocks/android_rotation.py old mode 100644 new mode 100755 diff --git a/kivyblocks/anz/__init__.py b/kivyblocks/anz/__init__.py old mode 100644 new mode 100755 diff --git a/kivyblocks/anz/bluetooth.py b/kivyblocks/anz/bluetooth.py old mode 100644 new mode 100755 diff --git a/kivyblocks/aplayer.py b/kivyblocks/aplayer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/backendfunction.py b/kivyblocks/backendfunction.py old mode 100644 new mode 100755 diff --git a/kivyblocks/baseWidget.py b/kivyblocks/baseWidget.py old mode 100644 new mode 100755 index 560d2b0..210801a --- a/kivyblocks/baseWidget.py +++ b/kivyblocks/baseWidget.py @@ -75,7 +75,7 @@ from .threadcall import HttpClient from .i18n import I18n from .widget_css import WidgetCSS from .ready import WidgetReady -from .utils import CSize, SUPER +from .utils import CSize from .swipebehavior import SwipeBehavior from .widgetExt.inputext import MyDropDown @@ -140,7 +140,7 @@ def ScatterBox(WidgetCSS, WidgetReady, ScatterLayout): class Box(WidgetCSS, WidgetReady, BoxLayout): def __init__(self, **kw): try: - SUPER(Box, self, kw) + super(Box, self).__init__(**kw) except Exception as e: print('Box(',kw,') Error') raise e @@ -157,9 +157,7 @@ class VBox(Box): Box.__init__(self, **kw) class SwipeBox(SwipeBehavior, Box): - def __init__(self, **kw): - SUPER(SwipeBox, self, kw) - + pass class Text(Label): lang=StringProperty('') @@ -182,7 +180,7 @@ class Text(Label): if not kwargs.get('text'): kwargs['text'] = kwargs.get('otext','') - SUPER(Text, self, kwargs) + super(Text, self).__init__(**kwargs) if self._i18n: self.i18n.addI18nWidget(self) if self.wrap: @@ -277,6 +275,7 @@ class Modal(VBox): self._target = None super(Modal, self).__init__(**kw) self.set_size_position() + print('size_hint=', self.size_hint, kw) self._target.bind(size=self.set_size_position) self.register_event_type('on_open') self.register_event_type('on_pre_open') @@ -299,7 +298,7 @@ class Modal(VBox): return super().on_touch_down(touch) - def on_target(self): + def on_target(self, o, target): w = Window if self.target is not None: w = Factory.Blocks.getWidgetById(self.target) @@ -324,9 +323,9 @@ class Modal(VBox): self.width = self.size_hint_x * self._target.width if self.size_hint_y: self.height = self.size_hint_y * self._target.height - print(self.width, self.height, - self.size_hint_x, self.size_hint_y, - self._target.size + print("size with target:", self.width, self.height, + self.size_hint, self.size_hint, + "target size=", self._target.size ) self.set_modal_position() @@ -392,7 +391,7 @@ class TimedModal(Modal): show_time = NumericProperty(0) def __init__(self, **kw): self.time_task = None - SUPER(TimedModal, self, kw) + super(TimedModal, self).__init__(**kw) def open(self, *args, **kw): if self.time_task is not None: diff --git a/kivyblocks/bgcolorbehavior.py b/kivyblocks/bgcolorbehavior.py old mode 100644 new mode 100755 diff --git a/kivyblocks/block_test.py b/kivyblocks/block_test.py old mode 100644 new mode 100755 diff --git a/kivyblocks/blocks.py b/kivyblocks/blocks.py old mode 100644 new mode 100755 index cfcd47a..8783844 --- a/kivyblocks/blocks.py +++ b/kivyblocks/blocks.py @@ -204,7 +204,7 @@ x = ClassX{klass_cnt}() return None if url.startswith('file://'): - return self.script.dispatch(url, **params) + return self.script.dispatch(url, params) elif url.startswith('http://') or url.startswith('https://'): try: hc = HttpClient() diff --git a/kivyblocks/blocksapp.py b/kivyblocks/blocksapp.py old mode 100644 new mode 100755 index 262abd7..9de0825 --- a/kivyblocks/blocksapp.py +++ b/kivyblocks/blocksapp.py @@ -60,10 +60,13 @@ class BlocksApp(App): with codecs.open(config.css.css_filename, 'r', 'utf-8') as f: d = json.load(f) self.buildCsses(d) - if config.css.css_url: - hc = HttpClient() - d = hc.get(self.realurl(config.css.css_url)) - self.buildCsses(d) + try: + if config.css.css_url: + hc = HttpClient() + d = hc.get(self.realurl(config.css.css_url)) + self.buildCsses(d) + except: + pass def on_rotate(self,*largs): self.current_rotation = Window.rotation @@ -76,10 +79,19 @@ class BlocksApp(App): register_css(k,v) def build(self): - i18n = I18n() + config = getConfig() + self.workers = Workers(maxworkers=config.maxworkers or 80) + self.workers.start() + try: + i18n = I18n() + except: + i18n = None self.platform = platform self.is_desktop = platform in ['win', 'linux', 'macosx'] - config = getConfig() + self.default_params = {} + if config.default_params: + self.default_params.update(config.default_params) + self.public_headers = { "platform":self.platform } @@ -88,8 +100,6 @@ class BlocksApp(App): Window.bind(on_request_close=self.on_close) Window.bind(on_rotate=self.on_rotate) Window.bind(size=self.device_info) - self.workers = Workers(maxworkers=config.maxworkers or 80) - self.workers.start() self.load_csses() self.running = True if config.root: @@ -163,7 +173,7 @@ class BlocksApp(App): } self.public_headers.update(device) - def on_close(self, *args): + def on_close(self, *args, **kwargs): self.workers.running = False return False diff --git a/kivyblocks/boxViewer.py b/kivyblocks/boxViewer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/circle_progress.py b/kivyblocks/circle_progress.py old mode 100644 new mode 100755 diff --git a/kivyblocks/clickable.py b/kivyblocks/clickable.py old mode 100644 new mode 100755 diff --git a/kivyblocks/color_definitions.py b/kivyblocks/color_definitions.py old mode 100644 new mode 100755 diff --git a/kivyblocks/colorcalc.py b/kivyblocks/colorcalc.py old mode 100644 new mode 100755 diff --git a/kivyblocks/command_action.py b/kivyblocks/command_action.py old mode 100644 new mode 100755 diff --git a/kivyblocks/dataloader.py b/kivyblocks/dataloader.py old mode 100644 new mode 100755 diff --git a/kivyblocks/date_picker.py b/kivyblocks/date_picker.py old mode 100644 new mode 100755 diff --git a/kivyblocks/dateinput.py b/kivyblocks/dateinput.py old mode 100644 new mode 100755 diff --git a/kivyblocks/defaultimage.py b/kivyblocks/defaultimage.py old mode 100644 new mode 100755 diff --git a/kivyblocks/dg.py b/kivyblocks/dg.py old mode 100644 new mode 100755 index 79558d9..e951294 --- a/kivyblocks/dg.py +++ b/kivyblocks/dg.py @@ -1,652 +1,646 @@ -import time -try: - import ujson as json -except: - import json -from functools import partial - -from kivy.logger import Logger -from kivy.uix.gridlayout import GridLayout -from kivy.uix.boxlayout import BoxLayout -from kivy.uix.scrollview import ScrollView -from kivy.uix.label import Label -from kivy.graphics import Fbo -from kivy.uix.button import ButtonBehavior -from kivy.clock import Clock -from kivy.properties import BooleanProperty, StringProperty, \ - OptionProperty, DictProperty, NumericProperty, ListProperty -from kivy.properties import ListProperty -from kivy.graphics import Color, Rectangle -from kivy.app import App -from kivy.factory import Factory - -from appPublic.dictObject import DictObject -from appPublic.uniqueID import getID -from appPublic.myTE import string_template_render - -from .utils import * -from .baseWidget import Text, HBox, VBox, Running -from .scrollpanel import ScrollPanel -from .paging import Paging, RelatedLoader -from .ready import WidgetReady -from .toolbar import Toolbar -from .bgcolorbehavior import BGColorBehavior -from .widget_css import WidgetCSS -from .uitype.factory import UiFactory - -class BLabel(ButtonBehavior, Text): - def __init__(self, **kw): - ButtonBehavior.__init__(self) - Text.__init__(self,**kw) - self.csscls = 'dummy' - -class Cell(ButtonBehavior, WidgetCSS, BoxLayout): - colume_name = StringProperty(None) - cell_type = OptionProperty('data', \ - options=['data', 'header']) - def __init__(self,row,desc, **kw): - """ - desc:{ - width, - datatype:fff - value: - format: - on_press: - } - """ - self.desc = desc - self.row = row - self.part = self.row.part - self.datagrid = self.part.datagrid - super().__init__(size_hint=(None,None), - width = self.desc['width'], - height = self.row.part.datagrid.rowHeight() - ) - self.csscls=self.row.part.datagrid.row_normal_css - if self.row.header: - self.csscls=self.row.part.datagrid.header_css - if desc['header']: - bl = Text(i18n=True, otext=str(desc['value']), - font_size=CSize(1),wrap=True, - halign='left', valign='middle' - ) - self.cell_type = 'header' - else: - self.cell_type = 'data' - bl = UiFactory.build_view_widget(desc,self.row.row_data) - if self.row.header and desc['name'] == '_checkable_action_': - id = self.row.row_data[idfield] - if self.row.part.datagrid.is_checked(id): - bl.setValue(True) - else: - bl.setValue(False) - bl.bind(select_state=self.row.checkable_action) - - self.colume_name = desc['name'] - if bl: - self.add_widget(bl) - -class Row(BoxLayout): - def __init__(self,part, rowdesc,header=False,data=None, **kw): - """ - rowdesc=[ - { - width, - name - value - on_press - } - - """ - self.part = part - self.datagrid = self.part.datagrid - self.header = header - self.row_data = data - self.row_id = None - self.linewidth = self.part.datagrid.linewidth - self.rowdesc = rowdesc - opts = kw.copy() - opts.update({ - "spacing":self.linewidth, - "orientation":"horizontal" - }) - super(Row, self).__init__(**opts) - self.height = self.part.datagrid.rowHeight() - self.init(0) - - def checkable_action(self, o, *args): - self.datagrid.set_checked_rows(self.row_id, o.select_state) - - def on_row_press(self, *args): - pass - - def init(self,t): - w = 0 - h = 0 - for c in self.rowdesc: - c['header'] = self.header - cell = Cell(self,c) - self.add_widget(cell) - cell.bind(on_press=self.part.datagrid.cell_pressed) - w += cell.width - self.size_hint = None,None - self.width = w + self.linewidth * (len(self.rowdesc)+1) - - def unselected(self): - self.select(False) - - def selected(self): - self.select(True) - - def select(self, flag): - for c in self.children: - if flag: - c.csscls = self.part.datagrid.row_selected_css - else: - c.csscls = self.part.datagrid.row_normal_css - -class Header(WidgetReady, ScrollPanel): - def __init__(self,part,**kw): - SUPER(Header, self, kw) - self.part = part - self.init(1) - self.bind(on_scroll_stop=self.part.datagrid.scrollstop) - if self.part.freeze_flag: - self.bar_width = 0 - self.bar_width = 0 - - def init(self,t): - rd = [ f.copy() for f in self.part.rowdesc ] - [ f.update({'value':self.part.fields[i].get('label', \ - self.part.fields[i].get('name'))}) \ - for i,f in enumerate(rd) ] - self.header = Row(self.part,rd,header=True) - self.add_widget(self.header) - self.height = self.header.height - -class Body(WidgetReady, ScrollPanel): - def __init__(self,part,**kw): - self.part = part - SUPER(Body, self, kw) - self._inner.spacing = self.part.datagrid.linewidth - self.size_hint=(1,1) - self.idRow = {} - self.bind(on_scroll_stop=self.part.datagrid.scrollstop) - if self.part.freeze_flag: - self.bar_width = 0 - - def addRow(self,id, data,index=0): - rd = [ f.copy() for f in self.part.rowdesc ] - [ f.update({'value':data.get(f['name'])}) for f in rd ] - row = Row(self.part,rd,data=data) - row.row_id = id - self.add_widget(row,index=index) - self.idRow[id] = row - return row - - def clearRows(self): - self.idRow = {} - self.clear_widgets() - - def delRowById(self,id): - row = self.idRow.get(id) - if row: - self.remove_widget(row) - if self.idRow.get(id): - del self.idRow[id] - - def getRowData(self,rowid): - return self.idRow[rowid].row_data - - def getRowHeight(self): - return self.part.datagrid.rowHeight() - - def get_row_by_id(self, rowid): - return self.idRow.get(rowid) - -class DataGridPart(WidgetReady, BoxLayout): - def __init__(self,dg, freeze_flag, fields): - self.datagrid = dg - self.fields = fields - self.freeze_flag = freeze_flag - self.fields_width = None - BoxLayout.__init__(self, orientation='vertical') - WidgetReady.__init__(self) - self.init(0) - - def setWidth(self): - if self.freeze_flag: - self.size_hint_x = None - self.width = self.getFieldsWidth() - - def getFieldsWidth(self): - if not self.fields_width: - width = 0 - for f in self.rowdesc: - width += f['width'] - self.fields_width = width - return self.fields_width - - def init(self,t): - rd = [] - for f in self.fields: - r = f.copy() - r['width'] = CSize(f.get('width',10)) - rd.append(r) - self.rowdesc = rd - self.setWidth() - kw = {} - if self.freeze_flag: - kw['width'] = self.fields_width - kw['size_hint'] = (None,None) - else: - kw['size_hint'] = (1,None) - kw['height'] = self.datagrid.rowHeight() - - self.header = None - if not self.datagrid.noheader: - self.header = Header(self,**kw) - self.add_widget(self.header) - inner = { - "widgettype":"VBox", - "options":{ - } - } - self.body = Body(self) - self.add_widget(self.body) - if not self.freeze_flag: - self.body.bind(pos=self.datagrid.bodyOnSize, - size=self.datagrid.bodyOnSize) - - def clearRows(self): - return self.body.clearRows() - - def addRow(self,id, data): - return self.body.addRow(id, data) - - def on_size(self, o, s=None): - if not hasattr(self, 'body'): - return - if hasattr(self, '_toolbar'): - if self._toolbar is not None: - self._toolbar.width = self.width - self.body.size_hint_y = None - if self.header: - self.body.height = self.height - self.header.height - else: - self.body.height = self.height - - -class DataGrid(VBox): - """ - DataGrid data format: - { - "widgettype":"DataGrid", - "dataloader":{ - "page":1, - "rows":60, - "dataurl":"eeee", - "params":{ - } - }, - "tailer":{ - "options":{ - } - "info":[ - "total_cnt", - "total_page", - "page_rows", - "curpage" - ], - "others":{ - } - }, - "row_height": CSize, - "header_css":"default", - "body_css":"default", - "spacing":1, - "fields":[ - { - "name":"field1", - "label":"Field1", - "datatype":"str", - "uitype":"code", - "value_field":, - "text_field": - }, - { - "name":"field2", - "label":"Field2", - "viewer":{ - block dic - } - } - ... - ] - "binds":[ - ] - } - """ - checkable = BooleanProperty(False) - row_selected = BooleanProperty(False) - row_normal_css = StringProperty('default') - row_selected_css = StringProperty('default') - header_css = StringProperty('default') - body_css = StringProperty('default') - row_height = NumericProperty(2) - noheader = BooleanProperty(False) - linewidth = NumericProperty(1) - toolbar = DictProperty(None) - dataloader = DictProperty(None) - fields = ListProperty(None) - tailer = DictProperty(None) - def __init__(self,**options): - if self.checkable: - self.fields.insert(0, { - "name":"_checkable_action_", - "label":" ", - "type":"checkbox", - "width":CSize(2), - "freeze_flag":True - }) - - self.checked_rows = [] - self.select_rowid = None - self.rowheight = None - self.on_sizeTask = None - self.selected_rowid = None - self.show_rows = 0 - self._toolbar = None - self.freeze_part = None - self.normal_part = None - SUPER(DataGrid, self, options) - self.freeze_fields = self.getPartFields(freeze_flag=True) - self.normal_fields = self.getPartFields(freeze_flag=False) - if not self.dataloader: - raise Exception('DataGrid need a DataLoader') - self._dataloader = RelatedLoader(target=self, **self.dataloader) - self._dataloader.bind(on_deletepage=self.delete_page) - self._dataloader.bind(on_pageloaded=self.add_page) - self._dataloader.bind(on_pageloaded=self.update_tailer_info) - self._dataloader.bind(on_newbegin=self.clearRows) - self.register_event_type('on_selected') - self.register_event_type('on_rowpress') - self.register_event_type('on_cellpress') - self.register_event_type('on_headerpress') - self.createDataGridPart() - self.createToolbar() - if self._toolbar: - self.add_widget(self._toolbar) - - b = BoxLayout(orientation='horizontal') - if self.freeze_part: - b.add_widget(self.freeze_part) - if self.normal_part: - b.add_widget(self.normal_part) - self.add_widget(b) - if self.tailer: - self.tailer_widgets = {} - self.build_tailer(self.tailer) - - def set_checked_rows(self, rowid, flag): - if flag and rowid not in self.checked_ids: - self.checked_ids.append(rowid) - if not flag: - self.checked_ids = [ id for id in self.checked_ids if id !=rowid] - def on_rowpress(self, *args): - print('on_rowpress fire, args=', args) - - def on_cellpress(self, *args): - print('on_cesspress fire, args=', args) - - def on_headerpress(self, *args): - print('on_headerpress fire, args=', args) - - def cell_pressed(self, o): - if o.cell_type == 'header': - self.dispatch('on_headerpress', o.colume_name) - return - row = o.row - if self.selected_rowid: - self.unselect_row(self.selected_rowid) - - self.selected_rowid = row.row_id - self.select_row(row.row_id) - self.dispatch('on_cellpress', o) - self.dispatch('on_rowpress', row) - self.dispatch('on_selected', row) - - def unselect_row(self, row_id): - if self.freeze_part: - row = self.freeze_part.body.get_row_by_id(row_id) - if not row: - return - row.unselected() - row = self.normal_part.body.get_row_by_id(row_id) - if not row: - return - row.unselected() - - def select_row(self, row_id): - if self.freeze_part: - row = self.freeze_part.body.get_row_by_id(row_id) - row.selected() - row = self.normal_part.body.get_row_by_id(row_id) - row.selected() - - def on_ready(self, *args): - self.loadData() - - def build_tailer(self, tailer_desc): - kw = tailer_desc.get('options', {}) - kw.update({ - 'size_hint_y':None, - 'height':self.rowheight - }) - w = HBox(**kw) - self.add_widget(w) - self.show_infos(w, tailer_desc.get('info')) - if tailer_desc.get('others'): - w1 = self.build_tailer_other(tailer_desc.get('others')) - if w1: - w.add_widget(w1) - - def update_tailer_info(self, *args): - if not hasattr(self, 'tailer_widgets'): - return - for n,w in self.tailer_widgets.items(): - w.text = self.loader_info(n) - - def show_infos(self, tailer_widget, info_names): - for n in info_names: - desc = { - "widgettype":"Text", - "options":{ - "otext":n, - "i18n":True, - } - } - w = Factory.Blocks().widgetBuild(desc) - tailer_widget.add_widget(w) - tailer_widget.add_widget(Label(text=':')) - self.tailer_widgets[n] = Label(text=self.loader_info(n)) - tailer_widget.add_widget(self.tailer_widgets[n]) - - def build_tailer_others(desc): - return Factory.Blocks().widgetBuild(desc) - - def loader_info(self, n): - if hasattr(self._dataloader, n): - txt=getattr(self._dataloader, n, 0) - if txt is None: - txt = '0' - txt = str(txt) - return txt - - def locater(self,pos): - self.normal_part.body.scroll_y = pos - if self.freeze_part: - self.freeze_part.body.scroll_y = pos - - def scrollstop(self,o,v=None): - if not self.noheader and o == self.normal_part.header: - self.normal_part.body.scroll_x = o.scroll_x - return - if o == self.normal_part.body: - if not self.noheader: - self.normal_part.header.scroll_x = o.scroll_x - if self.freeze_part: - self.freeze_part.body.scroll_y = o.scroll_y - if self.freeze_part and o == self.freeze_part.body: - self.normal_part.body.scroll_y = o.scroll_y - - if o.scroll_y <= 0.01: - self._dataloader.loadNextPage() - if o.scroll_y >= 0.99: - self._dataloader.loadPreviousPage() - - def getValue(self): - if not self.select_rowid: - return None - return self._getRowData(self.select_rowid) - - def _getRowData(self, rowid): - d = {} - if self.freeze_part: - d.update(self.freeze_part.body.getRowData(rowid)) - d.update(self.normal_part.body.getRowData(rowid)) - return DictObject(**d) - - def bodyOnSize(self,o,s): - if self.on_sizeTask is not None: - self.on_sizeTask.cancel() - self.on_sizeTask = Clock.schedule_once(self.calculateShowRows,0.3) - - def rowHeight(self): - if not self.rowheight: - self.rowheight = CSize(self.row_height) - return self.rowheight - - def calculateShowRows(self,t): - self.getShowRows() - self._dataloader.setPageRows(self.show_rows * 2) - - def getShowRows(self): - if self.show_rows == 0: - return 60 - self.show_rows = int(self.rowHeight() / self.normal_part.body.height) - return self.show_rows * 2 - - def clearRows(self, *args): - if self.freeze_part: - self.freeze_part.body.clearRows() - self.normal_part.body.clearRows() - - def add_page(self,o,data): - dir = data['dir'] - if not self.show_rows: - self.getShowRows() - - ids = [] - recs = data['data'] - idx = 0 - if dir == 'up': - recs.reverse() - idx = -1 - recs1 = recs[:self.show_rows] - recs2 = recs[self.show_rows:] - self._fbo = Fbo(size=self.size) - with self._fbo: - self._background_color = Color(0,0,0,1) - self._background_rect = Rectangle(size=self.size) - for r in recs1: - id = self.addRow(r,index=idx) - ids.append(id) - with self.canvas: - self._fbo_rect = Rectangle(size=self.size, - texture=self._fbo.texture) - - data['idx'] = idx - data['ids'] = ids - data['data'] = recs2 - f = partial(self.add_page_delay,data) - Clock.schedule_once(f, 0) - - def add_page_delay(self, data, *args): - recs = data['data'] - page = data['page'] - idx = data['idx'] - ids = data['ids'] - self._fbo = Fbo(size=self.size) - with self._fbo: - self._background_color = Color(0,0,0,1) - self._background_rect = Rectangle(size=self.size) - for r in recs: - id = self.addRow(r,index=idx) - ids.append(id) - with self.canvas: - self._fbo_rect = Rectangle(size=self.size, - texture=self._fbo.texture) - self._dataloader.bufferObjects(page,ids) - x = self._dataloader.getLocater() - self.locater(x) - - def delete_page(self,o,data): - for id in data: - self.delRow(id) - - def addRow(self,data, **kw): - id = getID() - f_row = None - if self.freeze_part: - self.freeze_part.body.addRow(id, data, **kw) - self.normal_part.body.addRow(id, data, **kw) - return id - - def delRow(self,id,**kw): - if self.freeze_part: - self.freeze_part.body.delRowById(id) - self.normal_part.body.delRowById(id) - - def createToolbar(self): - if self.toolbar: - self._toolbar = Toolbar(**self.toolbar) - - def on_selected(self,row): - print("DataGrid():on_selected fire") - - def loadData(self,*args, **kwargs): - kwargs['page'] = 1 - self.selected_rowid = None - self._dataloader.do_search(None,kwargs) - - def createDataGridPart(self): - self.freeze_part = None - self.normal_part = None - if self.freeze_fields: - self.freeze_part = DataGridPart(self,True, self.freeze_fields) - if self.normal_fields: - self.normal_part = DataGridPart(self, False, self.normal_fields) - - def getPartFields(self,freeze_flag:bool=False) -> list: - fs = [] - for f in self.fields: - if freeze_flag: - if f.get('freeze',False): - fs.append(f) - else: - if not f.get('freeze',False): - fs.append(f) - return fs - - def get_selected_data(self): - if not self.selected_rowid: - return {} - data = {} - row_id = self.selected_rowid - if self.freeze_part: - row = self.freeze_part.body.get_row_by_id(row_id) - data.update(row.row_data) - row = self.normal_part.body.get_row_by_id(row_id) - data.update(row.row_data) - return data +import time +try: + import ujson as json +except: + import json +from functools import partial + +from kivy.logger import Logger +from kivy.uix.gridlayout import GridLayout +from kivy.uix.boxlayout import BoxLayout +from kivy.uix.scrollview import ScrollView +from kivy.uix.label import Label +from kivy.graphics import Fbo +from kivy.uix.button import ButtonBehavior +from kivy.clock import Clock +from kivy.properties import BooleanProperty, StringProperty, \ + OptionProperty, DictProperty, NumericProperty, ListProperty +from kivy.properties import ListProperty +from kivy.graphics import Color, Rectangle +from kivy.app import App +from kivy.factory import Factory + +from appPublic.dictObject import DictObject +from appPublic.uniqueID import getID +from appPublic.myTE import string_template_render + +from .utils import * +from .baseWidget import Text, HBox, VBox +from .scrollpanel import ScrollPanel +from .paging import Paging, RelatedLoader +from .ready import WidgetReady +from .toolbar import Toolbar +from .bgcolorbehavior import BGColorBehavior +from .widget_css import WidgetCSS +from .uitype.factory import UiFactory + +class BLabel(ButtonBehavior, Text): + def __init__(self, **kw): + ButtonBehavior.__init__(self) + Text.__init__(self,**kw) + self.csscls = 'dummy' + +class Cell(ButtonBehavior, WidgetCSS, BoxLayout): + colume_name = StringProperty(None) + cell_type = OptionProperty('data', \ + options=['data', 'header']) + def __init__(self,row,desc, **kw): + """ + desc:{ + width, + datatype:fff + value: + format: + on_press: + } + """ + self.desc = desc + self.row = row + width = self.desc['width'] + height = self.row.part.datagrid.rowHeight() + print(f'Cell:{width=}, {height=},value={desc["value"]}') + super().__init__(size_hint=(None,None), + width=width, + bgcolor=[0.1,0.5,0.5], + height=height + ) + self.csscls=self.row.part.datagrid.row_normal_css + if self.row.header: + self.csscls=self.row.part.datagrid.header_css + if desc['header']: + bl = Text(i18n=True, text=str(desc['value']), + font_size=CSize(1),wrap=True, + halign='left', valign='middle' + ) + self.cell_type = 'header' + else: + self.cell_type = 'data' + bl = UiFactory.build_view_widget(desc,self.row.row_data) + self.colume_name = desc['name'] + if bl: + self.add_widget(bl) + +class Row(BoxLayout): + def __init__(self,part, rowdesc,header=False,data=None, **kw): + """ + rowdesc=[ + { + width, + name + value + on_press + } + + """ + self.part = part + self.header = header + self.row_data = data + self.row_id = None + self.linewidth = self.part.datagrid.linewidth + self.rowdesc = rowdesc + opts = kw.copy() + opts.update({ + "spacing":self.linewidth, + "orientation":"horizontal" + }) + super(Row, self).__init__(**opts) + self.height = self.part.datagrid.rowHeight() + self.init(0) + + def on_row_press(self, *args): + pass + + def init(self,t): + w = 0 + h = 0 + for c in self.rowdesc: + c['header'] = self.header + cell = Cell(self,c) + self.add_widget(cell) + cell.bind(on_press=self.part.datagrid.cell_pressed) + w += cell.width + self.size_hint = None,None + self.width = w + self.linewidth * (len(self.rowdesc)+1) + + def unselected(self): + self.select(False) + + def selected(self): + self.select(True) + + def select(self, flag): + for c in self.children: + if flag: + c.csscls = self.part.datagrid.row_selected_css + else: + c.csscls = self.part.datagrid.row_normal_css + +class Header(WidgetReady, ScrollPanel): + def __init__(self,part,**kw): + SUPER(Header, self, kw) + self.part = part + self.init(1) + self.bind(on_scroll_stop=self.part.datagrid.scrollstop) + if self.part.freeze_flag: + self.bar_width = 0 + self.bar_width = 0 + + def init(self,t): + rd = [ f.copy() for f in self.part.rowdesc ] + [ f.update({'value':self.part.fields[i].get('label', \ + self.part.fields[i].get('name'))}) \ + for i,f in enumerate(rd) ] + self.header = Row(self.part,rd,header=True) + self.add_widget(self.header) + self.size_hint_y = None + self.height = self.header.height + +class Body(WidgetReady, ScrollPanel): + def __init__(self,part,**kw): + self.part = part + SUPER(Body, self, kw) + self._inner.spacing = self.part.datagrid.linewidth + self.size_hint=(1,1) + self.idRow = {} + self.bind(on_scroll_stop=self.part.datagrid.scrollstop) + if self.part.freeze_flag: + self.bar_width = 0 + + def addRow(self,id, data,index=0): + rd = [ f.copy() for f in self.part.rowdesc ] + [ f.update({'value':data.get(f['name'])}) for f in rd ] + row = Row(self.part,rd,data=data) + row.row_id = id + self.add_widget(row,index=index) + self.idRow[id] = row + print(f'row size={row.size}, hint={row.size_hint}') + return row + + def clearRows(self): + self.idRow = {} + self.clear_widgets() + + def delRowById(self,id): + row = self.idRow.get(id) + if row: + self.remove_widget(row) + if self.idRow.get(id): + del self.idRow[id] + + def getRowData(self,rowid): + return self.idRow[rowid].row_data + + def getRowHeight(self): + return self.part.datagrid.rowHeight() + + def get_row_by_id(self, rowid): + return self.idRow.get(rowid) + +class DataGridPart(WidgetReady, BoxLayout): + def __init__(self,dg, freeze_flag, fields): + self.datagrid = dg + self.fields = fields + self.freeze_flag = freeze_flag + self.fields_width = None + BoxLayout.__init__(self, orientation='vertical') + WidgetReady.__init__(self) + self.init(0) + + def setWidth(self): + if self.freeze_flag: + self.size_hint_x = None + self.width = self.getFieldsWidth() + + def getFieldsWidth(self): + if not self.fields_width: + width = 0 + for f in self.rowdesc: + width += f['width'] + self.fields_width = width + return self.fields_width + + def init(self,t): + rd = [] + for f in self.fields: + r = f.copy() + r['width'] = CSize(f.get('width',10)) + rd.append(r) + self.rowdesc = rd + self.setWidth() + kw = {} + if self.freeze_flag: + kw['width'] = self.fields_width + kw['size_hint'] = (None,None) + else: + kw['size_hint'] = (1,None) + kw['height'] = self.datagrid.rowHeight() + + self.header = None + if not self.datagrid.noheader: + self.header = Header(self,**kw) + self.add_widget(self.header) + inner = { + "widgettype":"VBox", + "options":{ + } + } + self.body = Body(self) + self.add_widget(self.body) + if not self.freeze_flag: + self.body.bind(pos=self.datagrid.bodyOnSize, + size=self.datagrid.bodyOnSize) + + def clearRows(self): + return self.body.clearRows() + + def addRow(self,id, data): + return self.body.addRow(id, data) + + def on_size(self, o, s=None): + if not hasattr(self, 'body'): + return + if hasattr(self, '_toolbar'): + if self._toolbar is not None: + self._toolbar.width = self.width + self.body.size_hint_y = None + if self.header: + self.body.height = self.height - self.header.height + else: + self.body.height = self.height + + +class DataGrid(VBox): + """ + DataGrid data format: + { + "widgettype":"DataGrid", + "dataloader":{ + "page":1, + "rows":60, + "dataurl":"eeee", + "params":{ + } + }, + "tailer":{ + "options":{ + } + "info":[ + "total_cnt", + "total_page", + "page_rows", + "curpage" + ], + "others":{ + } + }, + "row_height": CSize, + "header_css":"default", + "body_css":"default", + "spacing":1, + "fields":[ + { + "name":"field1", + "label":"Field1", + "datatype":"str", + "uitype":"code", + "value_field":, + "text_field": + }, + { + "name":"field2", + "label":"Field2", + "viewer":{ + block dic + } + } + ... + ] + "binds":[ + ] + } + """ + row_selected = BooleanProperty(False) + row_normal_css = StringProperty('default') + row_selected_css = StringProperty('default') + header_css = StringProperty('default') + body_css = StringProperty('default') + row_height = NumericProperty(2) + noheader = BooleanProperty(False) + linewidth = NumericProperty(1) + toolbar = DictProperty(None) + dataloader = DictProperty(None) + fields = ListProperty(None) + tailer = DictProperty(None) + def __init__(self,**options): + self.select_rowid = None + self.rowheight = None + self.on_sizeTask = None + self.selected_rowid = None + self.show_rows = 0 + self._toolbar = None + self.freeze_part = None + self.normal_part = None + SUPER(DataGrid, self, options) + self.freeze_fields = self.getPartFields(freeze_flag=True) + self.normal_fields = self.getPartFields(freeze_flag=False) + if not self.dataloader: + raise Exception('DataGrid need a DataLoader') + self._dataloader = RelatedLoader(target=self, **self.dataloader) + self._dataloader.bind(on_deletepage=self.delete_page) + self._dataloader.bind(on_pageloaded=self.add_page) + self._dataloader.bind(on_pageloaded=self.update_tailer_info) + self._dataloader.bind(on_newbegin=self.clearRows) + self.register_event_type('on_selected') + self.register_event_type('on_rowpress') + self.register_event_type('on_cellpress') + self.register_event_type('on_headerpress') + self.createDataGridPart() + self.createToolbar() + if self._toolbar: + self.add_widget(self._toolbar) + + b = BoxLayout(orientation='horizontal') + if self.freeze_part: + b.add_widget(self.freeze_part) + if self.normal_part: + b.add_widget(self.normal_part) + self.add_widget(b) + if self.tailer: + self.tailer_widgets = {} + self.build_tailer(self.tailer) + + def on_rowpress(self, *args): + print('on_rowpress fire, args=', args) + + def on_cellpress(self, *args): + print('on_cellpress fire, args=', args) + + def on_headerpress(self, *args): + print('on_headerpress fire, args=', args) + + def cell_pressed(self, o): + if o.cell_type == 'header': + self.dispatch('on_headerpress', o.colume_name) + return + row = o.row + if self.selected_rowid: + self.unselect_row(self.selected_rowid) + + self.selected_rowid = row.row_id + self.select_row(row.row_id) + self.dispatch('on_cellpress', o) + self.dispatch('on_rowpress', row) + self.dispatch('on_selected', row) + + def unselect_row(self, row_id): + if self.freeze_part: + row = self.freeze_part.body.get_row_by_id(row_id) + if not row: + return + row.unselected() + row = self.normal_part.body.get_row_by_id(row_id) + if not row: + return + row.unselected() + + def select_row(self, row_id): + if self.freeze_part: + row = self.freeze_part.body.get_row_by_id(row_id) + row.selected() + row = self.normal_part.body.get_row_by_id(row_id) + row.selected() + + def on_ready(self, *args): + self.loadData() + + def build_tailer(self, tailer_desc): + kw = tailer_desc.get('options', {}) + kw.update({ + 'size_hint_y':None, + 'height':self.rowheight + }) + w = HBox(**kw) + self.add_widget(w) + self.show_infos(w, tailer_desc.get('info')) + if tailer_desc.get('others'): + w1 = self.build_tailer_other(tailer_desc.get('others')) + if w1: + w.add_widget(w1) + + def update_tailer_info(self, *args): + if not hasattr(self, 'tailer_widgets'): + return + for n,w in self.tailer_widgets.items(): + w.text = self.loader_info(n) + + def show_infos(self, tailer_widget, info_names): + for n in info_names: + desc = { + "widgettype":"Text", + "options":{ + "text":n, + "i18n":True, + } + } + w = Factory.Blocks().widgetBuild(desc) + tailer_widget.add_widget(w) + tailer_widget.add_widget(Label(text=':')) + self.tailer_widgets[n] = Label(text=self.loader_info(n)) + tailer_widget.add_widget(self.tailer_widgets[n]) + + def build_tailer_others(desc): + return Factory.Blocks().widgetBuild(desc) + + def loader_info(self, n): + if hasattr(self._dataloader, n): + txt=getattr(self._dataloader, n, 0) + if txt is None: + txt = '0' + txt = str(txt) + return txt + + def locater(self,pos): + self.normal_part.body.scroll_y = pos + if self.freeze_part: + self.freeze_part.body.scroll_y = pos + + def scrollstop(self,o,v=None): + if not self.noheader and o == self.normal_part.header: + self.normal_part.body.scroll_x = o.scroll_x + return + if o == self.normal_part.body: + if not self.noheader: + self.normal_part.header.scroll_x = o.scroll_x + if self.freeze_part: + self.freeze_part.body.scroll_y = o.scroll_y + if self.freeze_part and o == self.freeze_part.body: + self.normal_part.body.scroll_y = o.scroll_y + + if o.scroll_y <= 0.01: + self._dataloader.loadNextPage() + if o.scroll_y >= 0.99: + self._dataloader.loadPreviousPage() + + def getValue(self): + if not self.select_rowid: + return None + return self._getRowData(self.select_rowid) + + def _getRowData(self, rowid): + d = {} + if self.freeze_part: + d.update(self.freeze_part.body.getRowData(rowid)) + d.update(self.normal_part.body.getRowData(rowid)) + return DictObject(**d) + + def bodyOnSize(self,o,s): + if self.on_sizeTask is not None: + self.on_sizeTask.cancel() + self.on_sizeTask = Clock.schedule_once(self.calculateShowRows,0.3) + + def rowHeight(self): + if not self.rowheight: + self.rowheight = CSize(self.row_height) + return self.rowheight + + def calculateShowRows(self,t): + self.getShowRows() + self._dataloader.setPageRows(self.show_rows * 2) + + def getShowRows(self): + if self.show_rows == 0: + return 60 + self.show_rows = int(self.rowHeight() / self.normal_part.body.height) + return self.show_rows * 2 + + def clearRows(self, *args): + if self.freeze_part: + self.freeze_part.body.clearRows() + self.normal_part.body.clearRows() + + def add_page(self,o,data): + dir = data['dir'] + if not self.show_rows: + self.getShowRows() + + ids = [] + recs = data['data'] + idx = 0 + if dir == 'up': + recs.reverse() + idx = -1 + recs1 = recs[:self.show_rows] + recs2 = recs[self.show_rows:] + self._fbo = Fbo(size=self.size) + with self._fbo: + self._background_color = Color(0,0,0,1) + self._background_rect = Rectangle(size=self.size) + for r in recs1: + id = self.addRow(r,index=idx) + ids.append(id) + with self.canvas: + self._fbo_rect = Rectangle(size=self.size, + texture=self._fbo.texture) + + data['idx'] = idx + data['ids'] = ids + data['data'] = recs2 + f = partial(self.add_page_delay,data) + Clock.schedule_once(f, 0) + + def add_page_delay(self, data, *args): + recs = data['data'] + page = data['page'] + idx = data['idx'] + ids = data['ids'] + self._fbo = Fbo(size=self.size) + with self._fbo: + self._background_color = Color(0,0,0,1) + self._background_rect = Rectangle(size=self.size) + for r in recs: + id = self.addRow(r,index=idx) + ids.append(id) + with self.canvas: + self._fbo_rect = Rectangle(size=self.size, + texture=self._fbo.texture) + self._dataloader.bufferObjects(page,ids) + x = self._dataloader.getLocater() + self.locater(x) + + def delete_page(self,o,data): + for id in data: + self.delRow(id) + + def addRow(self,data, **kw): + # print('addRow()', data) + id = getID() + f_row = None + if self.freeze_part: + self.freeze_part.body.addRow(id, data, **kw) + self.normal_part.body.addRow(id, data, **kw) + return id + + def delRow(self,id,**kw): + if self.freeze_part: + self.freeze_part.body.delRowById(id) + self.normal_part.body.delRowById(id) + + def createToolbar(self): + if self.toolbar: + self._toolbar = Toolbar(**self.toolbar) + + def on_selected(self,row): + print("DataGrid():on_selected fire") + + def loadData(self,*args, **kwargs): + kwargs['page'] = 1 + self.selected_rowid = None + self._dataloader.do_search(None,kwargs) + + def createDataGridPart(self): + self.freeze_part = None + self.normal_part = None + if self.freeze_fields: + self.freeze_part = DataGridPart(self,True, self.freeze_fields) + if self.normal_fields: + self.normal_part = DataGridPart(self, False, self.normal_fields) + + def getPartFields(self,freeze_flag:bool=False) -> list: + fs = [] + for f in self.fields: + if freeze_flag: + if f.get('freeze',False): + fs.append(f) + else: + if not f.get('freeze',False): + fs.append(f) + return fs + + def show_size(self, *args, **kw): + print(f'dg:{self.size}') + print(f'normal_part:{self.normal_part.size}') + print(f'body:{self.normal_part.body.size}') + print(f'row:{self.normal_part.body.children[0].size}') + print(f'row:{self.normal_part.body.children[0].size}') + sp = self.normal_part.body.children[0] + print(f'rows={len(sp.children) - 1}') + for i, r in enumerate(sp.children): + print(f'{i} {r.size=}') + if self.normal_part.parent.parent == self: + print('part ok') + else: + print('part parent=', self.normal_part.parent) + if self.normal_part.body.parent == self.normal_part: + print('body ok') + + def get_selected_data(self): + if not self.selected_rowid: + return {} + data = {} + row_id = self.selected_rowid + if self.freeze_part: + row = self.freeze_part.body.get_row_by_id(row_id) + data.update(row.row_data) + row = self.normal_part.body.get_row_by_id(row_id) + data.update(row.row_data) + return data diff --git a/kivyblocks/download.py b/kivyblocks/download.py old mode 100644 new mode 100755 diff --git a/kivyblocks/externalwidgetmanager.py b/kivyblocks/externalwidgetmanager.py old mode 100644 new mode 100755 diff --git a/kivyblocks/ffpyplayer_video.py b/kivyblocks/ffpyplayer_video.py old mode 100644 new mode 100755 diff --git a/kivyblocks/filebrowser.py b/kivyblocks/filebrowser.py old mode 100644 new mode 100755 diff --git a/kivyblocks/form.py b/kivyblocks/form.py old mode 100644 new mode 100755 index b8f9275..69d5948 --- a/kivyblocks/form.py +++ b/kivyblocks/form.py @@ -32,6 +32,7 @@ form options "method" } "cols":"1" + "inputwidth", "labelwidth": "textsize": "inputheight": diff --git a/kivyblocks/gps.py b/kivyblocks/gps.py old mode 100644 new mode 100755 diff --git a/kivyblocks/hack_ffpyplayer.py b/kivyblocks/hack_ffpyplayer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/hierarchy.py b/kivyblocks/hierarchy.py old mode 100644 new mode 100755 diff --git a/kivyblocks/hostimage.py b/kivyblocks/hostimage.py old mode 100644 new mode 100755 diff --git a/kivyblocks/httpvplayer.py b/kivyblocks/httpvplayer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/i18n.py b/kivyblocks/i18n.py old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/.DS_Store b/kivyblocks/imgs/.DS_Store old mode 100644 new mode 100755 index 797bc45..90b7b93 Binary files a/kivyblocks/imgs/.DS_Store and b/kivyblocks/imgs/.DS_Store differ diff --git a/kivyblocks/imgs/Mute64x64.png b/kivyblocks/imgs/Mute64x64.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/Play64X64.png b/kivyblocks/imgs/Play64X64.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/Sound64x64.png b/kivyblocks/imgs/Sound64x64.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/backword.png b/kivyblocks/imgs/backword.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/broken.png b/kivyblocks/imgs/broken.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/bullet_arrow_down.png b/kivyblocks/imgs/bullet_arrow_down.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/bullet_arrow_right.png b/kivyblocks/imgs/bullet_arrow_right.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/cancel.png b/kivyblocks/imgs/cancel.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/checkbox-off.png b/kivyblocks/imgs/checkbox-off.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/checkbox-on.png b/kivyblocks/imgs/checkbox-on.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/clear.png b/kivyblocks/imgs/clear.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/conform.png b/kivyblocks/imgs/conform.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/crud_add.png b/kivyblocks/imgs/crud_add.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/crud_browser.png b/kivyblocks/imgs/crud_browser.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/crud_del.png b/kivyblocks/imgs/crud_del.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/crud_edit.png b/kivyblocks/imgs/crud_edit.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/crud_filter.png b/kivyblocks/imgs/crud_filter.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/delete.png b/kivyblocks/imgs/delete.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/doing.gif b/kivyblocks/imgs/doing.gif old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/download.png b/kivyblocks/imgs/download.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/error.png b/kivyblocks/imgs/error.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/folder.png b/kivyblocks/imgs/folder.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/icon_view.png b/kivyblocks/imgs/icon_view.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/info.png b/kivyblocks/imgs/info.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/kivymd_512.png b/kivyblocks/imgs/kivymd_512.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/kivymd_logo.png b/kivyblocks/imgs/kivymd_logo.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/list_view.png b/kivyblocks/imgs/list_view.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/loading.gif b/kivyblocks/imgs/loading.gif old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/loading1.gif b/kivyblocks/imgs/loading1.gif old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/menu.png b/kivyblocks/imgs/menu.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/musictrack.png b/kivyblocks/imgs/musictrack.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/musictrack_d.png b/kivyblocks/imgs/musictrack_d.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/next.png b/kivyblocks/imgs/next.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/next_d.png b/kivyblocks/imgs/next_d.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/org_sound.png b/kivyblocks/imgs/org_sound.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/org_sound_d.png b/kivyblocks/imgs/org_sound_d.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/origin.jpg b/kivyblocks/imgs/origin.jpg old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/pause.png b/kivyblocks/imgs/pause.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/pause_d.png b/kivyblocks/imgs/pause_d.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/photo.png b/kivyblocks/imgs/photo.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/picture_empty.png b/kivyblocks/imgs/picture_empty.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/play.png b/kivyblocks/imgs/play.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/play_d.png b/kivyblocks/imgs/play_d.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/power64x64.png b/kivyblocks/imgs/power64x64.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/previous.jpg b/kivyblocks/imgs/previous.jpg old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/quad_shadow-0.png b/kivyblocks/imgs/quad_shadow-0.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/quad_shadow-1.png b/kivyblocks/imgs/quad_shadow-1.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/quad_shadow-2.png b/kivyblocks/imgs/quad_shadow-2.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/quad_shadow.atlas b/kivyblocks/imgs/quad_shadow.atlas old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/question.png b/kivyblocks/imgs/question.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_shadow-0.png b/kivyblocks/imgs/rec_shadow-0.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_shadow-1.png b/kivyblocks/imgs/rec_shadow-1.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_shadow.atlas b/kivyblocks/imgs/rec_shadow.atlas old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_st_shadow-0.png b/kivyblocks/imgs/rec_st_shadow-0.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_st_shadow-1.png b/kivyblocks/imgs/rec_st_shadow-1.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_st_shadow-2.png b/kivyblocks/imgs/rec_st_shadow-2.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/rec_st_shadow.atlas b/kivyblocks/imgs/rec_st_shadow.atlas old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/record.png b/kivyblocks/imgs/record.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/replay.png b/kivyblocks/imgs/replay.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/replay_d.png b/kivyblocks/imgs/replay_d.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/return.png b/kivyblocks/imgs/return.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/right_menu.png b/kivyblocks/imgs/right_menu.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/round_shadow-0.png b/kivyblocks/imgs/round_shadow-0.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/round_shadow-1.png b/kivyblocks/imgs/round_shadow-1.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/round_shadow-2.png b/kivyblocks/imgs/round_shadow-2.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/round_shadow.atlas b/kivyblocks/imgs/round_shadow.atlas old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/running.gif b/kivyblocks/imgs/running.gif old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/save.png b/kivyblocks/imgs/save.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/search.png b/kivyblocks/imgs/search.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/stop.png b/kivyblocks/imgs/stop.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/stop64x64.png b/kivyblocks/imgs/stop64x64.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/transparent.png b/kivyblocks/imgs/transparent.png old mode 100644 new mode 100755 diff --git a/kivyblocks/imgs/upload.png b/kivyblocks/imgs/upload.png old mode 100644 new mode 100755 diff --git a/kivyblocks/kivymdPlugin.py b/kivyblocks/kivymdPlugin.py old mode 100644 new mode 100755 diff --git a/kivyblocks/kivysize.py b/kivyblocks/kivysize.py old mode 100644 new mode 100755 diff --git a/kivyblocks/landscopehide.py b/kivyblocks/landscopehide.py old mode 100644 new mode 100755 diff --git a/kivyblocks/localFolderLoader.py b/kivyblocks/localFolderLoader.py old mode 100644 new mode 100755 diff --git a/kivyblocks/login.py b/kivyblocks/login.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/__init__.py b/kivyblocks/mapview/__init__.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/_version.py b/kivyblocks/mapview/_version.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/clustered_marker_layer.py b/kivyblocks/mapview/clustered_marker_layer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/constants.py b/kivyblocks/mapview/constants.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/downloader.py b/kivyblocks/mapview/downloader.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/geojson.py b/kivyblocks/mapview/geojson.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/icons/cluster.png b/kivyblocks/mapview/icons/cluster.png old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/icons/marker.png b/kivyblocks/mapview/icons/marker.png old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/mbtsource.py b/kivyblocks/mapview/mbtsource.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/source.py b/kivyblocks/mapview/source.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/types.py b/kivyblocks/mapview/types.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/utils.py b/kivyblocks/mapview/utils.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mapview/view.py b/kivyblocks/mapview/view.py old mode 100644 new mode 100755 diff --git a/kivyblocks/markdown.py b/kivyblocks/markdown.py old mode 100644 new mode 100755 diff --git a/kivyblocks/material_resources.py b/kivyblocks/material_resources.py old mode 100644 new mode 100755 diff --git a/kivyblocks/message.py b/kivyblocks/message.py old mode 100644 new mode 100755 diff --git a/kivyblocks/mixin.py b/kivyblocks/mixin.py old mode 100644 new mode 100755 diff --git a/kivyblocks/modalbehavior.py b/kivyblocks/modalbehavior.py old mode 100644 new mode 100755 diff --git a/kivyblocks/multi_select.py b/kivyblocks/multi_select.py old mode 100644 new mode 100755 diff --git a/kivyblocks/newvideo.py b/kivyblocks/newvideo.py old mode 100644 new mode 100755 diff --git a/kivyblocks/objectViewer.py b/kivyblocks/objectViewer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/orientationlayout.py b/kivyblocks/orientationlayout.py old mode 100644 new mode 100755 diff --git a/kivyblocks/pagepanel.py b/kivyblocks/pagepanel.py old mode 100644 new mode 100755 diff --git a/kivyblocks/pagescontainer.py b/kivyblocks/pagescontainer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/paging.py b/kivyblocks/paging.py old mode 100644 new mode 100755 diff --git a/kivyblocks/player_osc.py b/kivyblocks/player_osc.py old mode 100644 new mode 100755 diff --git a/kivyblocks/playlist.py b/kivyblocks/playlist.py old mode 100644 new mode 100755 diff --git a/kivyblocks/price.py b/kivyblocks/price.py old mode 100644 new mode 100755 diff --git a/kivyblocks/pyinterpreter.py b/kivyblocks/pyinterpreter.py old mode 100644 new mode 100755 diff --git a/kivyblocks/qrdata.py b/kivyblocks/qrdata.py old mode 100644 new mode 100755 diff --git a/kivyblocks/ready.py b/kivyblocks/ready.py old mode 100644 new mode 100755 diff --git a/kivyblocks/register.py b/kivyblocks/register.py old mode 100644 new mode 100755 diff --git a/kivyblocks/responsivelayout.py b/kivyblocks/responsivelayout.py old mode 100644 new mode 100755 diff --git a/kivyblocks/script.py b/kivyblocks/script.py old mode 100644 new mode 100755 index ff6b1dd..91b2150 --- a/kivyblocks/script.py +++ b/kivyblocks/script.py @@ -12,6 +12,7 @@ from appPublic.myTE import MyTemplateEngine from appPublic.Singleton import SingletonDecorator from appPublic.dictObject import DictObject +from kivy.app import App from kivy.logger import Logger from kivy.utils import platform @@ -26,7 +27,7 @@ def set_script_env(n,v): class Script: def __init__(self): config = getConfig() - self.root = config.script_root + self.root = config.uihome[7:] if sep != '/': self.root = self.root.replace(sep, '/') # print('Script.root=', self.root) @@ -63,16 +64,17 @@ class Script: # print(f'script:script exists {sf_exists}') # print(f'script:config.json exists {conf_exists}') - def dispatch(self, url, **kw): + def dispatch(self, url, kw): filepath = self.url2filepath(url) # print('dispatch():url=', url, 'filepath=', filepath) for suffix, handler in self.handlers.items(): if filepath.endswith(suffix): env = self.env.copy() env.update(ScriptEnv()) - env.update(kw) + # env.update(kw) env['root_path'] = self.root env['url'] = url + env['params_kw'] = kw env['filepath'] = filepath h = handler(self, env) d = h.render() @@ -120,6 +122,9 @@ class BaseHandler: self.script = script self.env = env self.env['entire_url'] = self.entire_url + app = App.get_running_app() + if hasattr(app, 'default_params'): + self.env.update(app.default_params) self.env['real_filepath'] = self.real_filepath class TemplateHandler(BaseHandler): diff --git a/kivyblocks/scrollpanel.py b/kivyblocks/scrollpanel.py old mode 100644 new mode 100755 diff --git a/kivyblocks/serverImageViewer.py b/kivyblocks/serverImageViewer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/serviceControl.py b/kivyblocks/serviceControl.py old mode 100644 new mode 100755 diff --git a/kivyblocks/setconfig.py b/kivyblocks/setconfig.py old mode 100644 new mode 100755 diff --git a/kivyblocks/sizeposbehavior.py b/kivyblocks/sizeposbehavior.py old mode 100644 new mode 100755 diff --git a/kivyblocks/swipebehavior.py b/kivyblocks/swipebehavior.py old mode 100644 new mode 100755 diff --git a/kivyblocks/tab.py b/kivyblocks/tab.py old mode 100644 new mode 100755 diff --git a/kivyblocks/theme_picker.py b/kivyblocks/theme_picker.py old mode 100644 new mode 100755 diff --git a/kivyblocks/theming.py b/kivyblocks/theming.py old mode 100644 new mode 100755 diff --git a/kivyblocks/theming_dynamic_text.py b/kivyblocks/theming_dynamic_text.py old mode 100644 new mode 100755 diff --git a/kivyblocks/threadcall.py b/kivyblocks/threadcall.py old mode 100644 new mode 100755 index 250cdef..4aefc30 --- a/kivyblocks/threadcall.py +++ b/kivyblocks/threadcall.py @@ -4,6 +4,8 @@ import time from threading import Thread, Lock, BoundedSemaphore import requests from functools import wraps +from requests.packages import urllib3 +urllib3.disable_warnings() from kivy.event import EventDispatcher from kivy.clock import Clock @@ -110,10 +112,16 @@ class HttpClient(Http_Client): return cb(None,resp) except Exception as e: raise e + + app = App.get_running_app() + p = {} + if hasattr(app, 'default_params'): + p = App.get_running_app().default_params + p.update(params) kwargs = { "url":url, "method":method, - "params":params, + "params":p, "files":files, "stream":stream, "headers":headers diff --git a/kivyblocks/toggleitems.py b/kivyblocks/toggleitems.py old mode 100644 new mode 100755 diff --git a/kivyblocks/toolbar.py b/kivyblocks/toolbar.py old mode 100644 new mode 100755 diff --git a/kivyblocks/tree.py b/kivyblocks/tree.py old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Alimama_ShuHeiTi_Bold.ttf b/kivyblocks/ttf/Alimama_ShuHeiTi_Bold.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/DroidSansFallback.ttf b/kivyblocks/ttf/DroidSansFallback.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-Bold.ttf b/kivyblocks/ttf/Roboto-Bold.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-Italic.ttf b/kivyblocks/ttf/Roboto-Italic.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-Light.ttf b/kivyblocks/ttf/Roboto-Light.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-LightItalic.ttf b/kivyblocks/ttf/Roboto-LightItalic.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-Medium.ttf b/kivyblocks/ttf/Roboto-Medium.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-MediumItalic.ttf b/kivyblocks/ttf/Roboto-MediumItalic.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-Regular.ttf b/kivyblocks/ttf/Roboto-Regular.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-Thin.ttf b/kivyblocks/ttf/Roboto-Thin.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/Roboto-ThinItalic.ttf b/kivyblocks/ttf/Roboto-ThinItalic.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/TsangerYuYangT_W01_W01.ttf b/kivyblocks/ttf/TsangerYuYangT_W01_W01.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/TsangerYuYangT_W02_W02.ttf b/kivyblocks/ttf/TsangerYuYangT_W02_W02.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/TsangerYuYangT_W03_W03.ttf b/kivyblocks/ttf/TsangerYuYangT_W03_W03.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/TsangerYuYangT_W04_W04.ttf b/kivyblocks/ttf/TsangerYuYangT_W04_W04.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/TsangerYuYangT_W05_W05.ttf b/kivyblocks/ttf/TsangerYuYangT_W05_W05.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/ttf/materialdesignicons-webfont.ttf b/kivyblocks/ttf/materialdesignicons-webfont.ttf old mode 100644 new mode 100755 diff --git a/kivyblocks/twosides.py b/kivyblocks/twosides.py old mode 100644 new mode 100755 diff --git a/kivyblocks/udp_widget.py b/kivyblocks/udp_widget.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/__init__.py b/kivyblocks/uitype/__init__.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/amount.py b/kivyblocks/uitype/amount.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/code.py b/kivyblocks/uitype/code.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/date.py b/kivyblocks/uitype/date.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/factory.py b/kivyblocks/uitype/factory.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/float.py b/kivyblocks/uitype/float.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/int.py b/kivyblocks/uitype/int.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/password.py b/kivyblocks/uitype/password.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/text.py b/kivyblocks/uitype/text.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uitype/viewer.py b/kivyblocks/uitype/viewer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/upload.py b/kivyblocks/upload.py old mode 100644 new mode 100755 diff --git a/kivyblocks/uploadfile.py b/kivyblocks/uploadfile.py old mode 100644 new mode 100755 diff --git a/kivyblocks/utils.py b/kivyblocks/utils.py old mode 100644 new mode 100755 diff --git a/kivyblocks/version.py b/kivyblocks/version.py old mode 100644 new mode 100755 index 1e4826d..5bf52d5 --- a/kivyblocks/version.py +++ b/kivyblocks/version.py @@ -1 +1 @@ -__version__ = '0.4.7' +__version__ = '0.4.8' diff --git a/kivyblocks/videobehavior.py b/kivyblocks/videobehavior.py old mode 100644 new mode 100755 index 2becbde..0f5353a --- a/kivyblocks/videobehavior.py +++ b/kivyblocks/videobehavior.py @@ -342,6 +342,9 @@ class VideoBehavior(object): self.my_show_texture(texture, w, h) # self.texture = texture + def set_source(self, src): + self.v_src = src + def show_others(self, img): img = self.prehandle(img) w, h = img.get_size() diff --git a/kivyblocks/vplayer.py b/kivyblocks/vplayer.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/__init__.py b/kivyblocks/widgetExt/__init__.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/androidwebview.py b/kivyblocks/widgetExt/androidwebview.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/binstateimage.py b/kivyblocks/widgetExt/binstateimage.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/camera.py b/kivyblocks/widgetExt/camera.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/camerabutton.py b/kivyblocks/widgetExt/camerabutton.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/dataloader.py b/kivyblocks/widgetExt/dataloader.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/filedataloader.py b/kivyblocks/widgetExt/filedataloader.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/httpdataloader.py b/kivyblocks/widgetExt/httpdataloader.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/inputext.py b/kivyblocks/widgetExt/inputext.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/jsoncodeinput.py b/kivyblocks/widgetExt/jsoncodeinput.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/messager.py b/kivyblocks/widgetExt/messager.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/phonebutton.py b/kivyblocks/widgetExt/phonebutton.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/scrollwidget.py b/kivyblocks/widgetExt/scrollwidget.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/sqldataloadder.py b/kivyblocks/widgetExt/sqldataloadder.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widgetExt/tree.py b/kivyblocks/widgetExt/tree.py old mode 100644 new mode 100755 diff --git a/kivyblocks/widget_css.py b/kivyblocks/widget_css.py old mode 100644 new mode 100755 diff --git a/readme/opencv-android编译出错.md b/readme/opencv-android编译出错.md old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 diff --git a/test/README.md b/test/README.md old mode 100644 new mode 100755 diff --git a/test/buildozer.spec b/test/buildozer.spec old mode 100644 new mode 100755 diff --git a/test/conf/config.json b/test/conf/config.json old mode 100644 new mode 100755 diff --git a/test/gadget/conf/config.json b/test/gadget/conf/config.json old mode 100644 new mode 100755 diff --git a/test/gadget/main.py b/test/gadget/main.py old mode 100644 new mode 100755 diff --git a/test/main.py b/test/main.py old mode 100644 new mode 100755 diff --git a/test/mixin.py b/test/mixin.py old mode 100644 new mode 100755 diff --git a/test/rv.py b/test/rv.py old mode 100644 new mode 100755 diff --git a/test/script/conf/config.json b/test/script/conf/config.json old mode 100644 new mode 100755 diff --git a/test/script/main.py b/test/script/main.py old mode 100644 new mode 100755 diff --git a/test/script/scripts/boxlayout/behavior.ui b/test/script/scripts/boxlayout/behavior.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/boxlayout/modalbehavior.ui b/test/script/scripts/boxlayout/modalbehavior.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/boxlayout/normal.ui b/test/script/scripts/boxlayout/normal.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/index.ui b/test/script/scripts/index.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/input_m3u.ui b/test/script/scripts/input_m3u.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/input_url.ui b/test/script/scripts/input_url.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/mainmenu.ui b/test/script/scripts/mainmenu.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/python.ui b/test/script/scripts/python.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/t.ui b/test/script/scripts/t.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/t1.ui b/test/script/scripts/t1.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/video/behavior.ui b/test/script/scripts/video/behavior.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/video/behavior1.ui b/test/script/scripts/video/behavior1.ui old mode 100644 new mode 100755 diff --git a/test/script/scripts/welcome.ui b/test/script/scripts/welcome.ui old mode 100644 new mode 100755 diff --git a/test/scroll.py b/test/scroll.py old mode 100644 new mode 100755 diff --git a/test/ttdg.py b/test/ttdg.py old mode 100644 new mode 100755