Beispiel #1
0
 def get_string(widget):
     if isinstance(widget, Gtk.Entry):
         result = _u(widget.get_text())
     elif isinstance(widget, Gtk.ComboBoxText):
         index = widget.get_active()
         result = widget.options[index]
     elif isinstance(widget, Gtk.Grid):
         result = _u(widget.entry.get_text())
     else:
         raise TypeError(_("Unhandled widget class!"))
     return result
Beispiel #2
0
 def get_string(widget):
     if isinstance(widget, Gtk.Entry):
         result = _u(widget.get_text())
     elif isinstance(widget, Gtk.ComboBoxText):
         index = widget.get_active()
         result = widget.options[index]
     elif isinstance(widget, Gtk.Grid):
         result = _u(widget.entry.get_text())
     else:
         raise TypeError(_("Unhandled widget class!"))
     return result
Beispiel #3
0
    def _match_anywhere(self, completion, entrystr, iter, data):
        """
        Check if the entrystring is a substring of our text_column.

        Args:
            entrystr (str): The text extracted from the entry so far. Note that
                we do not use this at all. Instead we fetch
                ``self.get_entry().get_segment_text`` in order to get only the text
                of the currently edited segment.
            iter: Iterator position indicating the model row we check against.
                This works because
                ``self.get_entry()._on_changed`` makes sure that the completion
                model is set properly according to ``self.get_entry().current_segment``.
            data: Arbitrary user data.

        Returns:
            bool: ``True`` if ``self.get_entry.get_segment_text`` is a substring,
                ``False`` if not.

        Note this is a custom match function, for details on the general generic
        solution [please see|https://lazka.github.io/pgi-docs/#Gtk-3.0/
        callbacks.html#Gtk.EntryCompletionMatchFunc].
        """
        result = False
        entry = self.get_entry()
        modelstring = ''
        hit = self.get_model()[iter][0]
        # We only need to check if the string was matched at all. Otherwise
        # there are no 'segments' anyway.
        if hit and entry.match:
            modelstring = _u(hit)
            segment_text = entry.get_segment_text()
            result = segment_text in modelstring
        return result
    def get_config_value(self):
        """
        Return the id of the selected item.

        Returns:
            six.text_type: Identifier of the selected item
        """
        return _u(self.get_active_id())
    def get_config_value(self):
        """
        Return the id of the selected item.

        Returns:
            six.text_type: Identifier of the selected item
        """
        return _u(self.get_active_id())
    def get_config_value(self):
        """
        Return the selected path.

        Returns:
            six.text_type: Selected file path.
        """
        return _u(self._entry.get_text())
    def get_config_value(self):
        """
        Return the selected path.

        Returns:
            six.text_type: Selected file path.
        """
        return _u(self._entry.get_text())
Beispiel #8
0
 def test_update_initial_fact(self, current_fact_box, fact):
     """Make sure update re-creates as widgets as expected."""
     assert not current_fact_box.content.get_children()
     current_fact_box.update(fact)
     assert len(current_fact_box.content.get_children()) == 3
     label = current_fact_box.content.get_children()[0]
     expectation = '{activity.name}@{activity.category}'.format(activity=fact.activity)
     assert expectation in _u(label.get_text())
Beispiel #9
0
 def test_update_initial_fact(self, current_fact_box, fact):
     """Make sure update re-creates as widgets as expected."""
     assert not current_fact_box.content.get_children()
     current_fact_box.update(fact)
     assert len(current_fact_box.content.get_children()) == 3
     label = current_fact_box.content.get_children()[0]
     expectation = '{activity.name}@{activity.category}'.format(
         activity=fact.activity)
     assert expectation in _u(label.get_text())
Beispiel #10
0
 def get_time(widget):
     if isinstance(widget, Gtk.Entry):
         result = _u(widget.get_text())
         # We are tollerant against malformed time information.
         try:
             result = datetime.datetime.strptime(result, '%H:%M:%S').time()
         except ValueError:
             result = datetime.datetime.strptime(result, '%H:%M').time()
     else:
         raise TypeError(_("Unhandled widget class!"))
     return result
Beispiel #11
0
 def get_time(widget):
     if isinstance(widget, Gtk.Entry):
         result = _u(widget.get_text())
         # We are tollerant against malformed time information.
         try:
             result = datetime.datetime.strptime(result,
                                                 '%H:%M:%S').time()
         except ValueError:
             result = datetime.datetime.strptime(result, '%H:%M').time()
     else:
         raise TypeError(_("Unhandled widget class!"))
     return result
    def _on_choose_clicked(self, widget):
        """Open a dialog to select path and update entry widget with it."""
        toplevel = get_parent_window(self)

        dialog = Gtk.FileChooserDialog(_("Please choose a directory"), toplevel,
            Gtk.FileChooserAction.SAVE, (_("_Cancel"), Gtk.ResponseType.CANCEL,
                                         _("_Save"), Gtk.ResponseType.OK))
        dialog.set_filename(self.get_config_value())
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            self._entry.set_text(_u(dialog.get_filename()))

        dialog.destroy()
    def _on_choose_clicked(self, widget):
        """Open a dialog to select path and update entry widget with it."""
        toplevel = get_parent_window(self)

        dialog = Gtk.FileChooserDialog(_("Please choose a directory"),
                                       toplevel, Gtk.FileChooserAction.SAVE,
                                       (_("_Cancel"), Gtk.ResponseType.CANCEL,
                                        _("_Save"), Gtk.ResponseType.OK))
        dialog.set_filename(self.get_config_value())
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            self._entry.set_text(_u(dialog.get_filename()))

        dialog.destroy()
Beispiel #14
0
    def _on_changed(self, widget):
        """
        Callback triggered whenever entry text is changed.

        Its main task is to keep track of which segment of the raw fact string the
        user is currently editing. For this the whole string is inspected and matched
        against our regex. By comparing the current cursor position with individual
        matched segment spans a guess about which one is currently edited is made.
        """
        def get_segment(match):
            """
            Return the segment the cursor is currently in.

            Returns:
                text_type or None: Segment identifier or None if cursor not within any segment.
            """
            result = None
            cursor_position = self.get_position()

            segments = ['timeinfo', 'tags', 'description']
            if self._split_activity_autocomplete:
                segments.extend(('activity', 'category'))
            else:
                segments.append('activity+category')

            for segment in segments:
                start, end = _get_segment_boundaries(segment, match)
                if start <= cursor_position <= end:
                    result = segment

            return result

        def run_autocomplete(segment):
            completion = self.get_completion()
            completion.set_model(completion.segment_models[segment])

        self.match = helpers.decompose_raw_fact_string(_u(self.get_text()),
                                                       raw=True)
        # Do nothing if we could not 'match' the raw string.
        # Please note that the completions 'match function' will be run
        # regardless of what we do here.
        if self.match:
            self.current_segment = get_segment(self.match)
            if self.current_segment in ('activity', 'category',
                                        'activity+category'):
                run_autocomplete(self.current_segment)
    def get_config_value(self):
        """
        Return time entered into the widget.

        The entered time has to match either ``HH:MM:SS`` or ``HH:MM`` form,
        otherwise an error is thrown.

        Returns:
            datetime.time: Selected time.

        Raises:
            ValueError: When the text entered in the field does not constitute a valid time.
        """
        result = _u(self.get_text())
        # We are tollerant against malformed time information.
        try:
            result = datetime.datetime.strptime(result, '%H:%M:%S').time()
        except ValueError:
            result = datetime.datetime.strptime(result, '%H:%M').time()

        return result
Beispiel #16
0
    def get_config_value(self):
        """
        Return time entered into the widget.

        The entered time has to match either ``HH:MM:SS`` or ``HH:MM`` form,
        otherwise an error is thrown.

        Returns:
            datetime.time: Selected time.

        Raises:
            ValueError: When the text entered in the field does not constitute a valid time.
        """
        result = _u(self.get_text())
        # We are tollerant against malformed time information.
        try:
            result = datetime.datetime.strptime(result, '%H:%M:%S').time()
        except ValueError:
            result = datetime.datetime.strptime(result, '%H:%M').time()

        return result
Beispiel #17
0
    def _on_start_tracking_button(self, button):
        """
        Start a new *ongoing fact*.

        Note:
            Whilst we accept the full ``raw_fact`` syntax, we ignore any ``Fact.end``
            information encoded in the string. Unlike legacy hamster we *only*
            deal with *ongoing facts* in this widget.
        """

        # [FIXME]
        # This should be done in one place only. And the hamster-lib. If at all
        # via hamster-lib.helpers.
        def complete_tmp_fact(fact):
            """Apply fallback logic in case no start time has been encoded."""
            if not fact.start:
                fact.start = datetime.datetime.now()
            # Make sure we dismiss any extracted end information.
            fact.end = None
            return fact

        raw_fact = _u(self.raw_fact_entry.props.text)

        try:
            fact = Fact.create_from_raw_fact(raw_fact)
        except Exception as error:
            helpers.show_error(helpers.get_parent_window(self), error)
        else:
            fact = complete_tmp_fact(fact)

            try:
                fact = self._controler.store.facts.save(fact)
            except Exception as error:
                helpers.show_error(self.get_top_level(), error)
            else:
                self.emit('tracking-started')
                self._controler.signal_handler.emit('facts-changed')
                self.reset()
Beispiel #18
0
    def replace_segment_text(
        self,
        segment_string,
    ):
        """
        Replace the substring of the entry text that matches ``self.current_segment``.

        Args:
            segment_string (text_type): New text that is to replace the old.

        Returns:
            None
        """
        def add_prefix(segment, string):
            # [TODO]
            # Once autocompletion supports more segments with prefixes, this will
            # need to be extended.
            result = string
            if segment == 'category':
                result = '@{}'.format(string)
            return result

        if not self.match:
            return

        match = self.match
        segment = self.current_segment
        segment_string = add_prefix(segment, segment_string)
        segment_start, segment_end = _get_segment_boundaries(segment, match)
        old_string = _u(self.get_text())
        new_string = '{}{}{}'.format(
            old_string[:segment_start],
            segment_string,
            old_string[segment_end:],
        )
        self.set_text(new_string)
        self.set_position(segment_start + len(segment_string))
Beispiel #19
0
    def _on_start_tracking_button(self, button):
        """
        Start a new *ongoing fact*.

        Note:
            Whilst we accept the full ``raw_fact`` syntax, we ignore any ``Fact.end``
            information encoded in the string. Unlike legacy hamster we *only*
            deal with *ongoing facts* in this widget.
        """
        # [FIXME]
        # This should be done in one place only. And the hamster-lib. If at all
        # via hamster-lib.helpers.
        def complete_tmp_fact(fact):
            """Apply fallback logic in case no start time has been encoded."""
            if not fact.start:
                fact.start = datetime.datetime.now()
            # Make sure we dismiss any extracted end information.
            fact.end = None
            return fact

        raw_fact = _u(self.raw_fact_entry.props.text)

        try:
            fact = Fact.create_from_raw_fact(raw_fact)
        except Exception as error:
            helpers.show_error(self.get_toplevel(), error)
        else:
            fact = complete_tmp_fact(fact)

            try:
                fact = self._controler.store.facts.save(fact)
            except Exception as error:
                helpers.show_error(self.get_top_level(), error)
            else:
                self.emit('tracking-started')
                self._controler.signal_handler.emit('facts-changed')
                self.reset()
Beispiel #20
0
 def get_description_value():
     """Get unicode value from widget."""
     text_view = self._description_widget.get_child()
     text_buffer = text_view.get_buffer()
     start, end = text_buffer.get_bounds()
     return _u(text_buffer.get_text(start, end, True))
Beispiel #21
0
 def get_description_value():
     """Get unicode value from widget."""
     text_view = self._description_widget.get_child()
     text_buffer = text_view.get_buffer()
     start, end = text_buffer.get_bounds()
     return _u(text_buffer.get_text(start, end, True))
Beispiel #22
0
 def get_raw_fact_value():
     """Get text from raw fact entry field."""
     return _u(self._raw_fact_widget.get_text())
Beispiel #23
0
 def test__get_fact_label(self, current_fact_box, fact):
     """Make sure that the label matches expectations."""
     result = current_fact_box._get_fact_label(fact)
     assert isinstance(result, Gtk.Label)
     assert _u(result.get_text()) == text_type(fact)
Beispiel #24
0
 def test__get_fact_label(self, current_fact_box, fact):
     """Make sure that the label matches expectations."""
     result = current_fact_box._get_fact_label(fact)
     assert isinstance(result, Gtk.Label)
     assert _u(result.get_text()) == text_type(fact)
Beispiel #25
0
 def get_raw_fact_value():
     """Get text from raw fact entry field."""
     return _u(self._raw_fact_widget.get_text())
Beispiel #26
0
 def _on_match_selected(self, completion, model, iter):
     """Callback to be executed once a match is selected by the user."""
     entry = self.get_entry()
     name = _u(model[iter][0])
     entry.replace_segment_text(name)
     return True