class AlexLabelTest(AbstractComponentTest):
    def __init__(self):
        super().__init__()
        self.name = "Alex label test"

    def test_component(self, master, message_label):

        self.message_label = message_label
        self.master = master

        self.label1 = AlexLabel(master)
        self.label1.set('Label text:')
        self.label1.grid(row=0, column=0)

        self.entry1 = AlexEntry(master)
        self.entry1.set("Enter label text")
        self.entry1.grid(row=0, column=1)

        AlexButton(master, text='Set label text',
                   command=self._set_label_text).grid(row=1, column=0)
        AlexButton(master,
                   text='Set entry from label',
                   command=self._set_entry_from_label).grid(row=1, column=1)

    def _set_label_text(self):

        self.label1.set(self.entry1.get())
        self.entry1.set('')

    def _set_entry_from_label(self):

        self.entry1.set(self.label1.get())
class AbstractInputDialog:
    '''
    A basic dialog skeleton for input dialogs. For simple
    message dialogs use the native dialogs of tkinter.

    This provides a rather simple framework for fast creating
    dialogs that return user input to the calling component.
    
    The framework works like this:
    
    - Make a subclass of this class
    - Overwrite the create_dialog method. You need to
      call the method in this superclass to provide you
      with the basic frames in the dialog window.
      Add your input stuff to the interior frame and
      your buttons to the button_frame (there are methods
      to help you for this)
    - Make a subclass of the AbstractInputDialogPresenter
    - Create action methods in the presenter that
      are bound to the buttons in the dialog window
    - The actions that are considered to close the
      dialog must set the return_value property of
      the view. This will close the dialog window and
      return the return_value to the caller of activate
    - Inject the dialog presenter into the dialog
    - Inject the dialog into your component that wants to
      use it
    - Call the activate method in the dialog in your
      component. You need to set a callback for your
      value. This callback will be executed with a value
      when the presenter closes the dialog window
    '''
    def __init__(self, window_manager, presenter):
        self.window_manager = window_manager
        self.presenter = presenter
        self.window = None
        self.callback = None

    def create_dialog(self):
        '''
        Extend this method in your child class. It already
        provides three frames: interior, buttons_frame and
        errormessage. The errormessage frame already has
        a label that may be read and set by the errormessage
        property.
        To set default buttons in the button_frame, use the
        set default buttons.
        Other buttons may be set through the add_button method.
        '''

        self.window = self.window_manager.create_new_window()
        self.window.protocol("WM_DELETE_WINDOW",
                             lambda: self._set_return_value(None))
        self.window.transient()
        self.window.attributes('-topmost', True)
        self.window.withdraw()

        self.interior = Frame(self.window)
        self.interior.pack()

        self.buttons_frame = Frame(self.window)
        self.buttons_frame.pack()

        self.message_frame = Frame(self.window)
        self.message_frame.pack()

        self._errormessage = AlexLabel(self.message_frame)
        self._errormessage.pack(side=TOP)

    def add_button(self, label, callback):
        '''
        Fast setup method for buttons. Just provide
        a label and a callback and a button will be
        appended to the button_frame
        '''

        button = AlexButton(self.buttons_frame, command=callback)
        button.set(label)
        button.pack(side=LEFT, padx=5, pady=5)
        return button

    def set_default_buttons(self):
        '''
        This method may be used in child classes
        to set the default buttons OK and Cancel
        '''
        self.add_button(_('OK'), self.presenter.ok_action)
        self.add_button(_('Cancel'), self.presenter.cancel_action)

    def _get_errormessage(self):
        message = self._errormessage.get()
        if message == '':
            return None
        else:
            return message

    def _set_errormessage(self, message):
        if message == None:
            self._errormessage.set('')
        else:
            self._errormessage.set(message)

    def activate(self, callback, **kw):
        '''
        '''
        if self.window is None:
            self.create_dialog()

        self.config_dialog(**kw)

        if self.window is None:
            callback(None)
            return
        self.callback = callback

        self.presenter.view = self
        self.window.deiconify()
        self.window.grab_set()

    def config_dialog(self, **kw):

        pass

    def _set_return_value(self, value):
        self.window.grab_release()
        self.window.withdraw()
        self.callback(value)

    return_value = property(None, _set_return_value)
    errormessage = property(_get_errormessage, _set_errormessage)