New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r-click Edit Menu, multiple issues in Linux #375

Closed
mpmc opened this Issue Feb 13, 2018 · 9 comments

Comments

Projects
None yet
2 participants
@mpmc
Contributor

mpmc commented Feb 13, 2018

When clicking select all (after or without selecting copy first) from the edit menu I get the error..

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.6/tkinter/__init__.py", line 1702, in __call__
    return self.func(*args)
  File "/home/mark/.local/lib/python3.6/site-packages/appJar/appjar.py", line 3409, in <lambda>
    return lambda *args: funcName(param)
  File "/home/mark/.local/lib/python3.6/site-packages/appJar/appjar.py", line 9759, in <lambda>
    ('Select All', lambda e: self._copyAndPasteHelper("Select All"), "A", True if gui.GET_PLATFORM() == gui.MAC else False),
  File "/home/mark/.local/lib/python3.6/site-packages/appJar/appjar.py", line 9541, in _copyAndPasteHelper
    self.copyAndPaste.setUp(widget)
  File "/home/mark/.local/lib/python3.6/site-packages/appJar/appjar.py", line 13035, in setUp
    if widget.tag_ranges("sel"):
AttributeError: 'Menu' object has no attribute 'tag_ranges'

WIP code example.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  gui.py
#
#  Copyright 2018 Mark Clarkstone <git@markclarkstone.co.uk>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#
import gettext
import traceback
import appJar
import hs602

gettext.install('Hs602util')


class Gui(appJar.gui):
    """Simple HS602 utility using appJar."""
    def __init__(self, *args):
        super().__init__()
        self.title = '{}'.format(_('HS602 Utility'))
        self.addMenuEdit(False)
        self.controller = hs602.Callback()
        self.start()

    # Helper methods.
    def removeAllWidgets(self, *args, **kwargs):
        """Remove all widgets and set the default padding"""
        super().removeAllWidgets(*args, **kwargs)
        self.padding = 5, 5
        self.inpadding = 3, 3

    def start(self):
        """Trigger the default window."""
        # Let the user know what's going on.
        self.error('Crashy crashy!')
        #self.msg(_('Device discovery, please wait..'))
        # Register the callback.
        #self.controller.register('devices0', callback=self.discovery)

    def values(self, **kwargs):
        """Get all values, merge & return as dictionary.

        kwargs will be _appended_ to the input list.
        """
        merge = dict()
        # All available inputs.
        inputs = [
                  self.getAllOptionBoxes(),
                  self.getAllEntries(),
                  self.getAllCheckBoxes(),
                  self.getAllRadioButtons(),
                  self.getAllProperties(),
                  self.getAllScales(),
                  self.getAllMeters(),
                  self.getAllSpinBoxes(),
                  self.getAllListBoxes(),
                  self.getAllDatePickers(),
                  kwargs,
        ]
        for dictionary in inputs:
            merge.update(dictionary)
            for key, value in merge.items():
                # Remove start/end spaces from string values.
                try:
                    value = value.strip()
                except AttributeError:
                    pass
                # Only add if a value has been set.
                if not value:
                    continue
                merge[key] = value
        return merge

    # User interface methods.
    def error(self, exc):
        """Display an error."""
        label = {
            'title': 'Message',
            'value': '{}'.format(_('Sorry there\'s a problem, the '
                                   'details of which are below.\nIf '
                                   'the problem persists, please '
                                   'report it.\n\nThank you!')),
            'sticky': 'nw',
            'stretch': 'none',
            'pos': (0, 0),
        }
        button = {
            'title': '{}'.format('Quit'),
            'value': self.stop,
            'pos': (2, 0),
            'sticky': 'nesw',
            'stretch': 'none',
        }
        # Get the traceback for the text box.
        trace = _('No traceback available.')
        try:
            trace = '\n'.join(traceback.format_tb(exc.__traceback__))
        except AttributeError:
            pass
        textarea = {
            'title': 'Error details',
            'value': '{}\n\n{}'.format(exc, trace),
            'pos': (1, 0),
            'sticky': 'nesw',
            'stretch': 'both',
            'tip': '{}'.format(_('Exception or error information.'))
        }

        def show():
            # Reset the GUI!
            self.removeAllWidgets()
            # Add widgets - error label (top).
            self.label(**label)
            self.setLabelAlign(label.get('title'), 'left')
            # Quit button (bottom).
            self.button(**button)
            # Text area.
            self.text(**textarea)
            self.disableTextArea(textarea.get('title'))

        # Show the error.
        self.queueFunction(show)

    def msg(self, text=None):
        """Clear the widgets and a show message - used during callbacks.

        text: Optional message to show.
        """
        label = {
            'title': 'Information',
            'value': '{}'.format(text or _('\u231B Please wait..')),
        }
        # Clear and display the message.
        self.removeAllWidgets()
        self.label(**label)
        self.setLabelAlign(label.get('title'), 'center')

    def discovery(self, result):
        """Discovery and connection screen.

        :param result: list of discovered devices.
        """
        no_devices = {
            'title': '{}'.format(_('No devices were found on your '
                                   'network.')),
            'pos': (0, 0),
            'sticky': 'nw',
            'stretch': 'none',
        }
        # If we've not got a list bail.
        if not isinstance(result, list):
            return self.error(result)

        # Reset the window before displaying.
        self.removeAllWidgets()


def main(args):
    app = Gui(*args)
    app.go()
    return 0


if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

jarvisteach added a commit that referenced this issue Feb 13, 2018

@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

OK - finally in a situation where I can do easy cross-platform testing.

It works fine(ish) on Mac - but breaks all over the place on linux!

@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

OK - so a couple of issues here...

First, sometimes the r-click menu actually grabs focus, when it's displayed, this breaks everything, but is easily resolved - I'll exclude Menus from being able to grab focus.

Second, there seems to be an occasional delay of focus grabbing when r-clicking on another widget, so the previous widget still has focus when the r-click menu is shown, needs more digging...

This is all called by the way we have to setUp a menu each time it's shown, so maybe changing the sequence of events there might be more productive..

@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

This is also linked to issue #347

@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

There's also an issue on linux where default text is being recognised as selectable text

@mpmc

This comment has been minimized.

Contributor

mpmc commented Feb 13, 2018

Feel free to close this & move things over to #347.

jarvisteach added a commit that referenced this issue Feb 13, 2018

@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

Have stripped out lots of complicated code:

  • Every time events occurred on the relevant widgets, the r-click menu was being updated.
  • That's all gone, now
  • Every time the r-click menu is displayed, it's first disabled, then the relevant menu items are re-enabled
  • Also excluding Menu widgets & catching exceptions & logging them

Have also had to put a bit of a hack to make widgets with default text work - passing a reference to the gui, so we can call the relevant functions.

This seems to work much better on linux.

@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

Looking good on MAC too, although UNDO not quite right

@jarvisteach jarvisteach changed the title from next_release: AttributeError: 'Menu' object has no attribute 'tag_ranges' to r-click Edit Menu, multiple issues in Linux Feb 13, 2018

@jarvisteach jarvisteach added the bug label Feb 13, 2018

@jarvisteach jarvisteach added this to the 1.0 milestone Feb 13, 2018

jarvisteach added a commit that referenced this issue Feb 13, 2018

Simplified undo/redo #375
Replaced undo/redo with event_generate calls.

Removed reliance on `edit_modified` to decide if show undo.
@jarvisteach

This comment has been minimized.

Owner

jarvisteach commented Feb 13, 2018

Closing this issue, known problems:

  • Undo/redo not supported in entry dialogs (could add own support, but not planning to).
  • Undo/redo doesn't work well on TextArea - can't accurately determine if available.
  • Copy/Paste a little buggy on MAC - sometimes pastes by itself, known issue on MAC.
@mpmc

This comment has been minimized.

Contributor

mpmc commented Feb 14, 2018

It works perfect now on Linux :) Undo/redo can be removed from the menu if it fails :(.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment