예제 #1
0
    def _perform_do_branches(self, instance, branches, *args):
        '''If the branch name exists, try to checkout. If a new name, create
        the branch and checkout.
        If the code has modification, shows an alert and stops
        '''
        get_designer().close_popup()

        if self.repo.is_dirty():
            show_alert('Git checkout',
                       'Please, commit your changes before '
                       'switch branches.')
            return

        if not branches:
            return

        branch = branches[0]
        try:
            if branch in self.repo.heads:
                self.repo.heads[branch].checkout()
            else:
                self.repo.create_head(branch)
                self.repo.heads[branch].checkout()
            branch_name = self.repo.active_branch.name
            self.dispatch('on_branch', branch_name)
        except GitCommandError as e:
            show_alert('Git Branches', 'Failed to switch branch!\n' + str(e))
예제 #2
0
 def _on_options(self, instance, selected_items):
     if isinstance(self._original_options[0], list):
         new_value = eval(selected_items[0])
     else:
         new_value = selected_items[0]
     self.propvalue = new_value
     self.set_value(new_value)
     get_designer().close_popup()
예제 #3
0
 def _on_options(self, instance, selected_items):
     if isinstance(self._original_options[0], list):
         new_value = eval(selected_items[0])
     else:
         new_value = selected_items[0]
     self.propvalue = new_value
     self.set_value(new_value)
     get_designer().close_popup()
예제 #4
0
 def _perform_select_root_widget(self, instance, selected_item, *args):
     '''On Playground edit item selection
     :type selected_item: instance of selected array
     '''
     get_designer().close_popup()
     name = selected_item[0]
     # remove Root label from widget name
     if name.startswith('Root - '):
         name = name.replace('Root - ', '')
     self.load_widget(name)
예제 #5
0
 def _perform_select_root_widget(self, instance, selected_item, *args):
     '''On Playground edit item selection
     :type selected_item: instance of selected array
     '''
     get_designer().close_popup()
     name = selected_item[0]
     # remove Root label from widget name
     if name.startswith('Root - '):
         name = name.replace('Root - ', '')
     self.load_widget(name)
예제 #6
0
 def _perform_do_add(self, instance, selected_files, *args):
     '''Add the selected files to git index
     '''
     try:
         self.repo.index.add(selected_files)
         show_message('%d file(s) added to Git index' %
                      len(selected_files), 5, 'info')
         get_designer().close_popup()
     except GitCommandError as e:
         show_alert('Git Add', 'Failed to add files to Git!\n' + str(e))
예제 #7
0
    def _perform_do_commit(self, input, *args):
        '''Perform the git commit with data from InputDialog
        '''
        message = input.get_user_input()
        if self.repo.is_dirty():
            try:
                self.repo.git.commit('-am', message)
                show_message('Commit: ' + message, 5, 'info')
            except GitCommandError as e:
                show_alert('Git Commit', 'Failed to commit!\n' + str(e))
        else:
            show_alert('Git Commit', 'There is nothing to commit')

        get_designer().close_popup()
    def _perform_buildozer_init(self, *args):
        '''Copies the spec from new_templates/default.spec to the project
        folder
        '''
        get_designer().close_popup()

        proj_dir = get_current_project().path
        spec_file = os.path.join(proj_dir, 'buildozer.spec')

        _dir = os.path.dirname(designer.__file__)
        _dir = os.path.split(_dir)[0]
        templates_dir = os.path.join(_dir, 'new_templates')
        shutil.copy(os.path.join(templates_dir, 'default.spec'), spec_file)

        self.designer.designer_content.update_tree_view(get_current_project())
예제 #9
0
    def _perform_buildozer_init(self, *args):
        '''Copies the spec from new_templates/default.spec to the project
        folder
        '''
        get_designer().close_popup()

        proj_dir = get_current_project().path
        spec_file = os.path.join(proj_dir, 'buildozer.spec')

        _dir = os.path.dirname(designer.__file__)
        _dir = os.path.split(_dir)[0]
        templates_dir = os.path.join(_dir, 'new_templates')
        shutil.copy(os.path.join(templates_dir, 'default.spec'), spec_file)

        self.designer.designer_content.update_tree_view(get_current_project())
예제 #10
0
        def pull(*args):
            '''Do a pull in a separated thread
            '''
            try:
                remote_repo.pull(progress=progress)

                def set_progress_done(*args):
                    progress.label.text = 'Completed!'

                Clock.schedule_once(set_progress_done, 1)
                progress.stop()
                show_message('Git remote pull completed!', 5)
            except GitCommandError as e:
                progress.label.text = 'Failed to pull!\n' + str(e)
            get_designer().close_popup()
    def create_setup_py(self):
        '''Runs the GUI to create a setup.py file
        '''
        d = get_designer()
        if d.popup:
            return False
        proj_dir = get_current_project().path
        designer_content = self.designer.designer_content

        setup_path = os.path.join(proj_dir, 'setup.py')
        if os.path.exists(setup_path):
            show_alert('Create setup.py', 'setup.py already exists!')
            return False

        content = ToolSetupPy(path=setup_path)
        d.popup = Popup(title='Create setup.py',
                        content=content,
                        size_hint=(None, None),
                        size=(550, 350),
                        auto_dismiss=False)
        content.bind(on_cancel=d.close_popup)

        def on_create(*args):
            designer_content.update_tree_view(get_current_project())
            d.close_popup()

        content.bind(on_create=on_create)
        d.popup.open()
    def on_close_tab(self, instance, *args):
        '''Event handler to close icon
        :param instance: tab instance
        '''
        d = get_designer()
        if d.popup:
            return False

        self.switch_to(instance)
        if instance.has_modification:
            # show a dialog to ask if can close
            confirm_dlg = ConfirmationDialog(
                    'All unsaved changes will be lost.\n'
                    'Do you want to continue?')
            popup = Popup(
                    title='New',
                    content=confirm_dlg,
                    size_hint=(None, None),
                    size=('200pt', '150pt'),
                    auto_dismiss=False)

            def close_tab(*args):
                d.close_popup()
                self._perform_close_tab(instance)

            confirm_dlg.bind(
                    on_ok=close_tab,
                    on_cancel=d.close_popup)
            popup.open()
            d.popup = popup
        else:
            Clock.schedule_once(partial(self._perform_close_tab, instance))
    def open_file(self, path, rel_path, switch_to=True):
        '''This will open file for editing in the DesignerTabbedPanel.
        :param switch_to: if should switch to the new tab
        :param rel_path: relative file path
        :param path: absolute file path to open
        '''
        for i, tab_item in enumerate(self.tab_list):
            if hasattr(tab_item, 'rel_path') and tab_item.rel_path == rel_path:
                # self.switch_to(self.tab_list[len(self.tab_list) - i - 2])
                self.switch_to(tab_item)
                return

        panel_item = DesignerCloseableTab(title=os.path.basename(path))
        panel_item.bind(on_close=self.on_close_tab)
        f = open(path, 'r')
        scroll = PyScrollView()
        _py_code_input = scroll.code_input
        _py_code_input.text = f.read()
        _py_code_input.path = path
        _py_code_input.bind(
            on_show_edit=App.get_running_app().root.on_show_edit)
        _py_code_input.bind(saved=panel_item.on_tab_content_saved)
        _py_code_input.bind(error=panel_item.on_tab_content_error)
        f.close()

        d = get_designer()
        if _py_code_input not in d.code_inputs:
            d.code_inputs.append(_py_code_input)

        panel_item.content = scroll
        panel_item.rel_path = rel_path
        self.add_widget(panel_item)
        if switch_to:
            self.switch_to(self.tab_list[0])
예제 #14
0
    def do_diff(self, *args):
        '''Open a CodeInput with git diff
        '''
        diff = self.repo.git.diff()

        designer = get_designer()
        designer_content = designer.designer_content
        tabs = designer_content.tab_pannel

        # check if diff is visible on tabbed panel.
        # if so, update the text content
        for i, code_input in enumerate(tabs.list_py_code_inputs):
            if code_input == self.diff_code_input:
                tabs.switch_to(tabs.tab_list[len(tabs.tab_list) - i - 2])
                code_input.text = diff
                return

        # if not displayed, create or add it to the screen
        if self.diff_code_input is None:
            panel_item = DesignerTabbedPanelItem(text='Git diff')
            scroll = PyScrollView()
            _py_code_input = scroll.code_input
            _py_code_input.rel_file_path = 'designer.DesigerGit.diff_code_input'
            _py_code_input.text = diff
            _py_code_input.readonly = True
            _py_code_input.lexer = DiffLexer()
            tabs.list_py_code_inputs.append(_py_code_input)
            panel_item.content = scroll
            self.diff_code_input = panel_item
        else:
            self.diff_code_input.content.code_input.text = diff
        tabs.add_widget(self.diff_code_input)
        tabs.switch_to(tabs.tab_list[0])
예제 #15
0
    def on_touch_down(self, touch):
        '''Display the option chooser
        '''
        d = get_designer()
        if d.popup:
            return False
        if self.collide_point(*touch.pos):
            if self._chooser is None:
                fake_setting = FakeSettingList()
                fake_setting.allow_custom = False
                fake_setting.items = self._options
                fake_setting.desc = 'Property Options'
                fake_setting.group = 'property_options'
                content = SettingListContent(setting=fake_setting)
                self._chooser = content

            self._chooser.parent = None
            self._chooser.selected_items = [self.text]
            self._chooser.show_items()

            popup_width = min(0.95 * Window.width, 500)
            popup_height = min(0.95 * Window.height, 500)
            d.popup = Popup(content=self._chooser,
                            title='Property Options - ' + self.propname,
                            size_hint=(None, None),
                            size=(popup_width, popup_height),
                            auto_dismiss=False)

            self._chooser.bind(on_apply=self._on_options,
                               on_cancel=d.close_popup)

            d.popup.open()
            return True

        return False
예제 #16
0
    def on_close_tab(self, instance, *args):
        '''Event handler to close icon
        :param instance: tab instance
        '''
        d = get_designer()
        if d.popup:
            return False

        self.switch_to(instance)
        if instance.has_modification:
            # show a dialog to ask if can close
            confirm_dlg = ConfirmationDialog(
                    'All unsaved changes will be lost.\n'
                    'Do you want to continue?')
            popup = Popup(
                    title='New',
                    content=confirm_dlg,
                    size_hint=(None, None),
                    size=('200pt', '150pt'),
                    auto_dismiss=False)

            def close_tab(*args):
                d.close_popup()
                self._perform_close_tab(instance)

            confirm_dlg.bind(
                    on_ok=close_tab,
                    on_cancel=d.close_popup)
            popup.open()
            d.popup = popup
        else:
            Clock.schedule_once(partial(self._perform_close_tab, instance))
예제 #17
0
    def on_text(self, instance, value):
        '''Default event handler for 'on_text'
        '''
        if not self.kv_code_input:
            return

        d = get_designer()
        playground = d.ui_creator.playground
        self.kv_code_input.set_event_handler(self.eventwidget,
                                             self.eventname,
                                             self.text)
        if self.text and self.text[-1] == '.':
            if self.text == 'self.':
                self.show_drop_down_for_widget(self.eventwidget)
            ## TODO recursively call eventwidget.parent to get the root widget
            elif self.text == 'root.':
                self.show_drop_down_for_widget(playground.root)

            else:
                _id = self.text.replace('.', '')
                root = playground.root
                widget = None

                if _id in root.ids:
                    widget = root.ids[_id]

                if widget:
                    self.show_drop_down_for_widget(widget)

        elif self.dropdown:
            self.dropdown.dismiss()
    def set_value(self, value):
        '''This function first converts the value of the propwidget, then sets
           the new value. If there is some error in setting new value, then it
           sets the property value back to oldvalue
        '''

        self.have_error = False
        conversion_err = False
        oldvalue = getattr(self.propwidget, self.propname)
        try:
            if isinstance(self.propwidget.property(self.propname),
                          NumericProperty):

                if value == 'None' or value == '':
                    value = None
                else:
                    value = float(value)

        except Exception:
            conversion_err = True

        designer = get_designer()
        if not conversion_err:
            try:
                setattr(self.propwidget, self.propname, value)
                self.kv_code_input.set_property_value(self.propwidget,
                                                      self.propname, value,
                                                      self.proptype)
                if self.record_to_undo:
                    designer.undo_manager.push_operation(
                        PropOperation(self, oldvalue, value))
                self.record_to_undo = True
            except Exception:
                self.have_error = True
                setattr(self.propwidget, self.propname, oldvalue)
예제 #19
0
    def recursive_insert(self, node, treenode):
        '''This function will add a node to TreeView, by recursively travelling
           through the Root Widget's Tree.
        '''

        if node is None:
            return

        b = self._get_widget(node)
        d = get_designer()
        self.tree.add_node(b, treenode)
        class_rules = get_current_project().app_widgets
        root_widget = self.playground.root

        is_child_custom = False
        for rule_name in class_rules:
            if rule_name == type(node).__name__:
                is_child_custom = True
                break

        is_child_complex = False
        for widget in widgets:
            if widget[0] == type(node).__name__ and widget[1] == 'complex':
                is_child_complex = True
                break

        if root_widget == node or (not is_child_custom and
                                   not is_child_complex):
            if isinstance(node, TabbedPanel):
                self.insert_for_tabbed_panel(node, b)
            else:
                for child in node.children:
                    self.recursive_insert(child, b)
예제 #20
0
    def do_add(self, *args):
        '''Git select files from a list to add
        '''
        d = get_designer()
        if d.popup:
            return False
        files = self.repo.untracked_files
        if not files:
            show_alert('Git Add', 'All files are already indexed by Git')
            return

        # create the popup
        fake_setting = FakeSettingList()
        fake_setting.allow_custom = False
        fake_setting.items = files
        fake_setting.desc = 'Select files to add to Git index'

        content = SettingListContent(setting=fake_setting)
        popup_width = min(0.95 * Window.width, 500)
        popup_height = min(0.95 * Window.height, 500)
        popup = Popup(
            content=content, title='Git - Add files', size_hint=(None, None),
            size=(popup_width, popup_height), auto_dismiss=False)

        content.bind(on_apply=self._perform_do_add,
                     on_cancel=d.close_popup)

        content.show_items()
        d.popup = popup
        popup.open()
예제 #21
0
    def create_setup_py(self):
        '''Runs the GUI to create a setup.py file
        '''
        d = get_designer()
        if d.popup:
            return False
        proj_dir = get_current_project().path
        designer_content = self.designer.designer_content

        setup_path = os.path.join(proj_dir, 'setup.py')
        if os.path.exists(setup_path):
            show_alert('Create setup.py', 'setup.py already exists!')
            return False

        content = ToolSetupPy(path=setup_path)
        d.popup = Popup(title='Create setup.py', content=content,
                        size_hint=(None, None), size=(550, 350),
                        auto_dismiss=False)
        content.bind(on_cancel=d.close_popup)

        def on_create(*args):
            designer_content.update_tree_view(get_current_project())
            d.close_popup()

        content.bind(on_create=on_create)
        d.popup.open()
예제 #22
0
    def do_branches(self, *args):
        '''Shows a list of git branches and allow to change the current one
        '''
        d = get_designer()
        if d.popup:
            return False
        branches = []
        for b in self.repo.heads:
            branches.append(b.name)

        # create the popup
        fake_setting = FakeSettingList()
        fake_setting.allow_custom = True
        fake_setting.items = branches
        fake_setting.desc = 'Checkout to the selected branch. \n' \
                'You can type a name to create a new branch'
        fake_setting.group = 'git_branch'

        content = SettingListContent(setting=fake_setting)
        popup_width = min(0.95 * Window.width, 500)
        popup_height = min(0.95 * Window.height, 500)
        popup = Popup(
            content=content, title='Git - Branches', size_hint=(None, None),
            size=(popup_width, popup_height), auto_dismiss=False)

        content.bind(on_apply=self._perform_do_branches,
                     on_cancel=d.close_popup)

        content.selected_items = [self.repo.active_branch.name]
        content.show_items()
        d.popup = popup
        popup.open()
예제 #23
0
    def set_value(self, value):
        '''This function first converts the value of the propwidget, then sets
           the new value. If there is some error in setting new value, then it
           sets the property value back to oldvalue
        '''

        self.have_error = False
        conversion_err = False
        oldvalue = getattr(self.propwidget, self.propname)
        try:
            if isinstance(self.propwidget.property(self.propname),
                          NumericProperty):

                if value == 'None' or value == '':
                    value = None
                else:
                    value = float(value)

        except Exception:
            conversion_err = True

        designer = get_designer()
        if not conversion_err:
            try:
                setattr(self.propwidget, self.propname, value)
                self.kv_code_input.set_property_value(self.propwidget,
                                                      self.propname, value,
                                                      self.proptype)
                if self.record_to_undo:
                    designer.undo_manager.push_operation(
                        PropOperation(self, oldvalue, value))
                self.record_to_undo = True
            except Exception:
                self.have_error = True
                setattr(self.propwidget, self.propname, oldvalue)
예제 #24
0
    def open_file(self, path, rel_path, switch_to=True):
        '''This will open file for editing in the DesignerTabbedPanel.
        :param switch_to: if should switch to the new tab
        :param rel_path: relative file path
        :param path: absolute file path to open
        '''
        for i, tab_item in enumerate(self.tab_list):
            if hasattr(tab_item, 'rel_path') and tab_item.rel_path == rel_path:
                # self.switch_to(self.tab_list[len(self.tab_list) - i - 2])
                self.switch_to(tab_item)
                return

        panel_item = DesignerCloseableTab(title=os.path.basename(path))
        panel_item.bind(on_close=self.on_close_tab)
        f = open(path, 'r')
        scroll = PyScrollView()
        _py_code_input = scroll.code_input
        _py_code_input.text = f.read()
        _py_code_input.path = path
        _py_code_input.bind(
            on_show_edit=App.get_running_app().root.on_show_edit)
        _py_code_input.bind(saved=panel_item.on_tab_content_saved)
        _py_code_input.bind(error=panel_item.on_tab_content_error)
        f.close()

        d = get_designer()
        if _py_code_input not in d.code_inputs:
            d.code_inputs.append(_py_code_input)

        panel_item.content = scroll
        panel_item.rel_path = rel_path
        self.add_widget(panel_item)
        if switch_to:
            self.switch_to(self.tab_list[0])
 def on_text(self, *args):
     '''Listen text changes
     '''
     if self.focus:
         self.saved = False
         d = get_designer()
         get_current_project().saved = False
예제 #26
0
    def _clean_old_kv(self, path):
        '''
        Removes widgets and rules already processed to this file
        :param path: file path - the same that in app_widgets
        '''
        for key in dict(self.app_widgets):
            wd = self.app_widgets[key]
            if path != wd.kv_path:
                continue
            wdg = get_app_widget(wd)
            if wdg is None:
                p = get_designer().ui_creator.playground
                if p.root_name == wd.name:
                    wdg = p._last_root
                if not wdg:
                    continue
            if wd.is_dynamic:
                del self.app_widgets[key]

            rules = Builder.match(wdg)

            # Cleaning widget rules
            for _rule in rules:
                for _tuple in Builder.rules[:]:
                    if _tuple[1] == _rule:
                        Builder.rules.remove(_tuple)
                        if wd.is_dynamic:
                            Factory.unregister(wd.name.split('@')[0])

            # Cleaning class rules
            for rule in Builder.rules[:]:
                if rule[1].name == '<' + wd.name + '>':
                    Builder.rules.remove(rule)
                    break
    def _clean_old_kv(self, path):
        '''
        Removes widgets and rules already processed to this file
        :param path: file path - the same that in app_widgets
        '''
        for key in dict(self.app_widgets):
            wd = self.app_widgets[key]
            if path != wd.kv_path:
                continue
            wdg = get_app_widget(wd)
            if wdg is None:
                p = get_designer().ui_creator.playground
                if p.root_name == wd.name:
                    wdg = p._last_root
                if not wdg:
                    continue
            if wd.is_dynamic:
                del self.app_widgets[key]

            rules = Builder.match(wdg)

            # Cleaning widget rules
            for _rule in rules:
                for _tuple in Builder.rules[:]:
                    if _tuple[1] == _rule:
                        Builder.rules.remove(_tuple)
                        if wd.is_dynamic:
                            Factory.unregister(wd.name.split('@')[0])

            # Cleaning class rules
            for rule in Builder.rules[:]:
                if rule[1].name == '<' + wd.name + '>':
                    Builder.rules.remove(rule)
                    break
예제 #28
0
        def push(*args):
            '''Do a push in a separated thread
            '''
            try:
                remote_repo.push(self.repo.active_branch.name,
                                 progress=progress)

                def set_progress_done(*args):
                    progress.label.text = 'Completed!'

                Clock.schedule_once(set_progress_done, 1)
                progress.stop()
                show_message('Git remote push completed!', 5, 'info')
            except GitCommandError as e:
                progress.label.text = 'Failed to push!\n' + str(e)
                show_message('Failed to push', 5, 'error')
            get_designer().close_popup()
예제 #29
0
 def _perform_close_tab(self, tab, *args):
     # remove code_input from list
     if hasattr(tab.content, 'code_input'):
         code = tab.content.code_input
         d = get_designer()
         if code in d.code_inputs:
             d.code_inputs.remove(code)
     # remove tab
     self.remove_widget(tab)
     if self.tab_list:
         self.switch_to(self.tab_list[0])
 def _perform_close_tab(self, tab, *args):
     # remove code_input from list
     if hasattr(tab.content, 'code_input'):
         code = tab.content.code_input
         d = get_designer()
         if code in d.code_inputs:
             d.code_inputs.remove(code)
     # remove tab
     self.remove_widget(tab)
     if self.tab_list:
         self.switch_to(self.tab_list[0])
예제 #31
0
    def find_target(self, x, y, target, widget=None):
        '''This widget is used to find the widget which collides with x,y
        '''
        if target is None or not target.collide_point(x, y):
            return None

        x, y = target.to_local(x, y)
        d = get_designer()
        class_rules = get_current_project().app_widgets

        for child in target.children:
            is_child_custom = False
            for rule_name in class_rules:
                if rule_name == type(child).__name__:
                    is_child_custom = True
                    break

            is_child_complex = False
            for _widget in widgets:
                if _widget[0] == type(child).__name__ and \
                                _widget[1] == 'complex':
                    is_child_complex = True
                    break

            # if point lies in custom wigdet's child then return custom widget
            if is_child_custom or is_child_complex:
                if not widget and self._custom_widget_collides(child, x, y):
                    return child

                elif widget:
                    if isinstance(child, TabbedPanel):
                        if child.current_tab:
                            _item = self.find_target(
                                x, y, child.current_tab.content)
                            return _item

                    else:
                        return target

            elif isinstance(child.parent, Carousel):
                t = self.find_target(x, y, child, widget)
                return t

            else:
                if not child.collide_point(x, y):
                    continue

                if not self.allowed_target_for(child, widget) and not \
                        child.children:
                    continue

                return self.find_target(x, y, child, widget)

        return target
예제 #32
0
    def load_widget(self, widget_name, update_kv_lang=True):
        '''Load and display and widget given its name.
        If widget is not found, shows information on status bar and clear
        the playground
        :param widget_name name of the widget to display
        :param update_kv_lang if True, reloads the kv file. If False, keep the
            kv lang text
        '''
        d = get_designer()
        if d.popup:
            # if has a popup, it's not using playground
            return False
        widgets = get_current_project().app_widgets
        # if displaying no widget or this widget is not know
        if self.root is None or self.root_app_widget is None or \
                widget_name not in widgets:
            self._perform_load_widget(widget_name, update_kv_lang)
            return
        # if a know widget, continue
        target = widgets[widget_name]

        # check if we are switching kv files
        if target.kv_path != self.root_app_widget.kv_path and \
                not self.kv_code_input.saved:

            file_name = os.path.basename(self.root_app_widget.kv_path)
            _confirm_dlg = ConfirmationDialogSave(
                'The %s was not saved. \n'
                'If you continue, your modifications will be lost.\n'
                'Do you want to save and continue?' % file_name)

            @ignore_proj_watcher
            def save_and_load(*args):
                get_current_project().save()
                self._perform_load_widget(widget_name, True)

            def dont_save(*args):
                d.close_popup()
                self._perform_load_widget(widget_name, True)

            _confirm_dlg.bind(on_save=save_and_load,
                              on_dont_save=dont_save,
                              on_cancel=d.close_popup)

            d.popup = Popup(title='Change Widget',
                            content=_confirm_dlg,
                            size_hint=(None, None),
                            size=('400pt', '150pt'),
                            auto_dismiss=False)
            d.popup.open()
            return
        self._perform_load_widget(widget_name, update_kv_lang)
예제 #33
0
    def load_widget(self, widget_name, update_kv_lang=True):
        '''Load and display and widget given its name.
        If widget is not found, shows information on status bar and clear
        the playground
        :param widget_name name of the widget to display
        :param update_kv_lang if True, reloads the kv file. If False, keep the
            kv lang text
        '''
        d = get_designer()
        if d.popup:
            # if has a popup, it's not using playground
            return False
        widgets = get_current_project().app_widgets
        # if displaying no widget or this widget is not know
        if self.root is None or self.root_app_widget is None or \
                widget_name not in widgets:
            self._perform_load_widget(widget_name, update_kv_lang)
            return
        # if a know widget, continue
        target = widgets[widget_name]

        # check if we are switching kv files
        if target.kv_path != self.root_app_widget.kv_path and \
                not self.kv_code_input.saved:

            file_name = os.path.basename(self.root_app_widget.kv_path)
            _confirm_dlg = ConfirmationDialogSave(
                'The %s was not saved. \n'
                'If you continue, your modifications will be lost.\n'
                'Do you want to save and continue?' % file_name
            )

            @ignore_proj_watcher
            def save_and_load(*args):
                get_current_project().save()
                self._perform_load_widget(widget_name, True)

            def dont_save(*args):
                d.close_popup()
                self._perform_load_widget(widget_name, True)

            _confirm_dlg.bind(
                on_save=save_and_load,
                on_dont_save=dont_save,
                on_cancel=d.close_popup)

            d.popup = Popup(title='Change Widget', content=_confirm_dlg,
                            size_hint=(None, None), size=('400pt', '150pt'),
                            auto_dismiss=False)
            d.popup.open()
            return
        self._perform_load_widget(widget_name, update_kv_lang)
예제 #34
0
 def do_commit(self, *args):
     '''Git commit
     '''
     d = get_designer()
     if d.popup:
         return False
     input_dlg = InputDialog('Commit message: ')
     d.popup = Popup(title='Git Commit', content=input_dlg,
                     size_hint=(None, None), size=('300pt', '150pt'),
                     auto_dismiss=False)
     input_dlg.bind(on_confirm=self._perform_do_commit,
                    on_cancel=d.close_popup)
     d.popup.open()
     return True
예제 #35
0
    def parse_kv(self, src, path):
        '''
        Parses a KV file with Builder.load_string. Identify root widgets and
        add them to self.root_widgets dict
        :param path: path of the kv file
        :param src: kv string
        :return boolean indicating if succeed in parsing the file
        '''
        self._clean_old_kv(path)
        root = None
        try:
            root = Builder.load_string(src, filename=os.path.basename(path))
        except Exception as e:
            self._errors.append(str(e))
            d = get_designer()
            d.ui_creator.kv_code_input.have_error = True
            return False
        # first, if a root widget was found, maps it
        if root:
            root_widgets = re.findall(KV_ROOT_WIDGET, src, re.MULTILINE)
            root_name = type(root).__name__
            for r in root_widgets:
                if r != root_name:
                    continue
                if r in self.app_widgets:
                    wdg = self.app_widgets[r]
                else:
                    wdg = AppWidget()
                wdg.name = r
                if path:
                    wdg.kv_path = path
                wdg.is_root = True
                wdg.instance = root
                if wdg not in self.app_widgets:
                    self.app_widgets[r] = wdg

        # now, get all custom widgets
        app_widgets = re.findall(KV_APP_WIDGET, src, re.MULTILINE)
        for a in app_widgets:
            wdg = self.app_widgets[a] if a in self.app_widgets else AppWidget()
            wdg.name = a
            if path:
                wdg.kv_path = path
            wdg.is_dynamic = '@' in a
            # dynamic widgets are not preloaded by py files
            if wdg not in self.app_widgets:
                self.app_widgets[a] = wdg

        return True
    def parse_kv(self, src, path):
        '''
        Parses a KV file with Builder.load_string. Identify root widgets and
        add them to self.root_widgets dict
        :param path: path of the kv file
        :param src: kv string
        :return boolean indicating if succeed in parsing the file
        '''
        self._clean_old_kv(path)
        root = None
        try:
            root = Builder.load_string(src, filename=os.path.basename(path))
        except Exception as e:
            self._errors.append(str(e))
            d = get_designer()
            d.ui_creator.kv_code_input.have_error = True
            return False
        # first, if a root widget was found, maps it
        if root:
            root_widgets = re.findall(KV_ROOT_WIDGET, src, re.MULTILINE)
            root_name = type(root).__name__
            for r in root_widgets:
                if r != root_name:
                    continue
                if r in self.app_widgets:
                    wdg = self.app_widgets[r]
                else:
                    wdg = AppWidget()
                wdg.name = r
                if path:
                    wdg.kv_path = path
                wdg.is_root = True
                wdg.instance = root
                if wdg not in self.app_widgets:
                    self.app_widgets[r] = wdg

        # now, get all custom widgets
        app_widgets = re.findall(KV_APP_WIDGET, src, re.MULTILINE)
        for a in app_widgets:
            wdg = self.app_widgets[a] if a in self.app_widgets else AppWidget()
            wdg.name = a
            if path:
                wdg.kv_path = path
            wdg.is_dynamic = '@' in a
            # dynamic widgets are not preloaded by py files
            if wdg not in self.app_widgets:
                self.app_widgets[a] = wdg

        return True
예제 #37
0
    def _setup_everything(self, *args):
        '''To setup all the references in between widget
        '''

        self.kv_code_input.playground = self.playground
        self.playground.kv_code_input = self.kv_code_input
        self.playground.kv_code_input.bind(
            on_reload_kv=self.playground.on_reload_kv)
        self.playground.widgettree = self.widgettree
        self.propertyviewer.kv_code_input = self.kv_code_input
        self.eventviewer.kv_code_input = self.kv_code_input
        self.py_console.remove_widget(self.py_console.children[1])
        d = get_designer()
        if self.kv_code_input not in d.code_inputs:
            d.code_inputs.append(self.kv_code_input)
예제 #38
0
    def validate_shortcut(self, *args):
        '''Check if it's a valid shortcut and if it's being used somewhere else
        Updates the error label and return a boolean
        '''
        # restore default values
        self.valid = True
        self.error = ''

        valid = False
        if (self.has_ctrl or self.has_shift or self.has_alt) and self.key:
            valid = True

        if self.key in [
                'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9'
                'f10', 'f11', 'f12'
        ]:
            valid = True

        modifier = []
        if self.has_ctrl:
            modifier.append('ctrl')
        if self.has_shift:
            modifier.append('shift')
        if self.has_alt:
            modifier.append('alt')
        modifier.sort()
        value = str(modifier) + ' + ' + self.key
        # check if shortcut exist
        d = get_designer()
        if value and value in d.shortcuts.map:
            shortcut = d.shortcuts.map[value]
            if shortcut[1] != self.config_name:
                valid = False
                self.error = 'Shortcut already being used at ' + shortcut[1]

        if valid:
            self.value = value
            self.error = ''
        else:
            self.value = ''
            if not self.error:
                self.error = 'This shortcut is not valid'

        self.valid = valid
        return valid
예제 #39
0
    def _update_menu(self, *args):
        '''Update the Git ActionSubMenu content.
        If a valid repo is open, git tools will be available.
        Is not a git repo, git init is available.
        '''
        self.remove_children()
        d = get_designer()
        loader = None
        if d:
            loader = get_current_project().path

        if loader:
            self.disabled = False
            if self.is_repo:
                btn_commit = DesignerSubActionButton(text='Commit')
                btn_commit.bind(on_press=self.do_commit)

                btn_add = DesignerSubActionButton(text='Add...')
                btn_add.bind(on_press=self.do_add)

                btn_branches = DesignerSubActionButton(text='Branches...')
                btn_branches.bind(on_press=self.do_branches)

                btn_diff = DesignerSubActionButton(text='Diff')
                btn_diff.bind(on_press=self.do_diff)

                btn_push = DesignerSubActionButton(text='Push')
                btn_push.bind(on_press=self.do_push)

                btn_pull = DesignerSubActionButton(text='Pull')
                btn_pull.bind(on_press=self.do_pull)

                self.add_widget(btn_commit)
                self.add_widget(btn_add)
                self.add_widget(btn_branches)
                self.add_widget(btn_diff)
                self.add_widget(btn_push)
                self.add_widget(btn_pull)
            else:
                btn_init = DesignerSubActionButton(text='Init repo')
                btn_init.bind(on_press=self.do_init)
                self.add_widget(btn_init)
            self._add_widget()
        else:
            self.disabled = True
예제 #40
0
    def validate_shortcut(self, *args):
        '''Check if it's a valid shortcut and if it's being used somewhere else
        Updates the error label and return a boolean
        '''
        # restore default values
        self.valid = True
        self.error = ''

        valid = False
        if (self.has_ctrl or self.has_shift or self.has_alt) and self.key:
            valid = True

        if self.key in ['f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9'
                        'f10', 'f11', 'f12']:
            valid = True

        modifier = []
        if self.has_ctrl:
            modifier.append('ctrl')
        if self.has_shift:
            modifier.append('shift')
        if self.has_alt:
            modifier.append('alt')
        modifier.sort()
        value = str(modifier) + ' + ' + self.key
        # check if shortcut exist
        d = get_designer()
        if value and value in d.shortcuts.map:
            shortcut = d.shortcuts.map[value]
            if shortcut[1] != self.config_name:
                valid = False
                self.error = 'Shortcut already being used at ' + shortcut[1]

        if valid:
            self.value = value
            self.error = ''
        else:
            self.value = ''
            if not self.error:
                self.error = 'This shortcut is not valid'

        self.valid = valid
        return valid
예제 #41
0
    def validate_shortcut(self, *args):
        """Check if it's a valid shortcut and if it's being used somewhere else
        Updates the error label and return a boolean
        """
        # restore default values
        self.valid = True
        self.error = ""

        valid = False
        if (self.has_ctrl or self.has_shift or self.has_alt) and self.key:
            valid = True

        if self.key in ["f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9" "f10", "f11", "f12"]:
            valid = True

        modifier = []
        if self.has_ctrl:
            modifier.append("ctrl")
        if self.has_shift:
            modifier.append("shift")
        if self.has_alt:
            modifier.append("alt")
        modifier.sort()
        value = str(modifier) + " + " + self.key
        # check if shortcut exist
        d = get_designer()
        if value and value in d.shortcuts.map:
            shortcut = d.shortcuts.map[value]
            if shortcut[1] != self.config_name:
                valid = False
                self.error = "Shortcut already being used at " + shortcut[1]

        if valid:
            self.value = value
            self.error = ""
        else:
            self.value = ""
            if not self.error:
                self.error = "This shortcut is not valid"

        self.valid = valid
        return valid
예제 #42
0
    def show_buildozer_spec_editor(self, project):
        """Loads the buildozer.spec file and adds a new tab with the
        Buildozer Spec Editor
        :param project: instance of the current project
        """
        for i, child in enumerate(self.tab_list):
            if isinstance(child.content, BuildozerSpecEditor):
                self.switch_to(child)
                return child

        spec_editor = get_designer().spec_editor
        if spec_editor.SPEC_PATH != os.path.join(project.path, "buildozer.spec"):
            spec_editor.load_settings(project.path)

        panel_spec_item = DesignerCloseableTab(title="Spec Editor")
        panel_spec_item.bind(on_close=self.on_close_tab)
        panel_spec_item.content = spec_editor
        panel_spec_item.rel_path = "buildozer.spec"
        self.add_widget(panel_spec_item)
        self.switch_to(self.tab_list[0])
    def show_buildozer_spec_editor(self, project):
        '''Loads the buildozer.spec file and adds a new tab with the
        Buildozer Spec Editor
        :param project: instance of the current project
        '''
        for i, child in enumerate(self.tab_list):
            if isinstance(child.content, BuildozerSpecEditor):
                self.switch_to(child)
                return child

        spec_editor = get_designer().spec_editor
        if spec_editor.SPEC_PATH != \
                os.path.join(project.path, 'buildozer.spec'):
            spec_editor.load_settings(project.path)

        panel_spec_item = DesignerCloseableTab(title="Spec Editor")
        panel_spec_item.bind(on_close=self.on_close_tab)
        panel_spec_item.content = spec_editor
        panel_spec_item.rel_path = 'buildozer.spec'
        self.add_widget(panel_spec_item)
        self.switch_to(self.tab_list[0])
예제 #44
0
    def on_widget_select_pressed(self, *args):
        '''Event handler to playground widget selector press
        '''
        d = get_designer()
        if d.popup:
            return False
        widgets = get_current_project().app_widgets
        app_widgets = []
        for name in widgets.keys():
            widget = widgets[name]
            if widget.is_root:
                name = 'Root - ' + name
            app_widgets.append(name)

        fake_setting = FakeSettingList()
        fake_setting.allow_custom = False
        fake_setting.items = app_widgets
        fake_setting.desc = 'Select the Widget to edit on Playground'
        fake_setting.group = 'playground_widget'

        content = SettingListContent(setting=fake_setting)
        popup_width = min(0.95 * Window.width, 500)
        popup_height = min(0.95 * Window.height, 500)
        d.popup = Popup(
            content=content,
            title='Playground - Edit Widget',
            size_hint=(None, None),
            size=(popup_width, popup_height),
            auto_dismiss=False
        )

        content.bind(on_apply=self._perform_select_root_widget,
                     on_cancel=d.close_popup)

        content.selected_items = [self.root_name]
        if self.root_app_widget and self.root_app_widget.is_root:
            content.selected_items = ['Root - ' + self.root_name]
        content.show_items()

        d.popup.open()
예제 #45
0
    def remove_widget_from_parent(self,
                                  widget,
                                  from_undo=False,
                                  from_kv=False):
        '''This function is used to remove widget its parent.
        :param from_undo: is comming from an undo action
        :param widget: widget to be removed
        '''

        parent = None
        d = get_designer()
        if not widget:
            return

        removed_str = ''
        if not from_kv:
            removed_str = self.kv_code_input.remove_widget_from_parent(widget)
        if widget != self.root:
            parent = widget.parent
            if parent is None and hasattr(widget, 'KD__last_parent'):
                parent = widget.KD__last_parent
            if isinstance(parent.parent, Carousel):
                parent.parent.remove_widget(widget)
            elif isinstance(parent, ScreenManager):
                if isinstance(widget, Screen):
                    parent.remove_widget(widget)
                else:
                    parent.real_remove_widget(widget)
            else:
                parent.remove_widget(widget)
        else:
            self.root.parent.remove_widget(self.root)
            self.root = None

        # if is designer
        if hasattr(d, 'ui_creator'):
            d.ui_creator.widgettree.refresh()
        if not from_undo and hasattr(d, 'ui_creator'):
            d.undo_manager.push_operation(
                WidgetOperation('remove', widget, parent, self, removed_str))
예제 #46
0
    def do_pull(self, *args):
        '''Open a list of remotes to pull remote data.
        If there is not remote, shows an alert
        '''
        d = get_designer()
        if d.popup:
            return False
        if not self.validate_remote():
            show_alert('Git - Remote Authentication',
                       'To use Git remote you need to enter your ssh password')
            return
        remotes = []
        for r in self.repo.remotes:
            remotes.append(r.name)
        if not remotes:
            show_alert('Git Pull Remote', 'There is no git remote configured!')
            return

        # create the popup
        fake_setting = FakeSettingList()
        fake_setting.allow_custom = False
        fake_setting.items = remotes
        fake_setting.desc = 'Pull data from the selected remote'
        fake_setting.group = 'git_remote'

        content = SettingListContent(setting=fake_setting)
        popup_width = min(0.95 * Window.width, 500)
        popup_height = min(0.95 * Window.height, 500)
        popup = popup = Popup(
            content=content, title='Git - Pull Remote', size_hint=(None, None),
            size=(popup_width, popup_height), auto_dismiss=False)

        content.bind(on_apply=self._perform_do_pull,
                     on_cancel=d.close_popup)

        content.selected_items = [remotes[0]]
        content.show_items()
        d.popup = popup
        popup.open()