Philipp Hörist pushed to branch mainwindow at gajim / gajim

Commits:

8 changed files:

Changes:

  • gajim/chat_control.py
    ... ... @@ -180,8 +180,8 @@ def __init__(self, parent_win, jid, acct, session, resource=None):
    180 180
             content_area.add(self.info_bar_label)
    
    181 181
             self.info_bar.set_no_show_all(True)
    
    182 182
     
    
    183
    -        self.xml.vbox2.pack_start(self.info_bar, False, True, 5)
    
    184
    -        self.xml.vbox2.reorder_child(self.info_bar, 1)
    
    183
    +        self.xml.textview_box.pack_start(self.info_bar, False, True, 5)
    
    184
    +        self.xml.textview_box.reorder_child(self.info_bar, 1)
    
    185 185
     
    
    186 186
             # List of waiting infobar messages
    
    187 187
             self.info_bar_queue = []
    

  • gajim/chat_control_base.py
    ... ... @@ -49,6 +49,7 @@
    49 49
     from gajim import gtkgui_helpers
    
    50 50
     
    
    51 51
     from gajim.gui.conversation.view import ConversationView
    
    52
    +from gajim.gui.conversation.scrolled import ScrolledView
    
    52 53
     from gajim.gui.dialogs import DialogButton
    
    53 54
     from gajim.gui.dialogs import ConfirmationDialog
    
    54 55
     from gajim.gui.dialogs import PastePreviewDialog
    
    ... ... @@ -166,38 +167,18 @@ def __init__(self, parent_win, widget_name, jid, acct,
    166 167
     
    
    167 168
             # Create ConversationView and connect signals
    
    168 169
             self.conversation_view = ConversationView(self.account, self.contact)
    
    169
    -        id_ = self.conversation_view.connect('quote', self.on_quote)
    
    170
    -        self.handlers[id_] = self.conversation_view
    
    171
    -        id_ = self.conversation_view.connect(
    
    172
    -            'load-history', self._on_load_history)
    
    173
    -        self.handlers[id_] = self.conversation_view
    
    170
    +        self.conversation_view.connect('quote', self.on_quote)
    
    171
    +
    
    174 172
             id_ = self.conversation_view.connect(
    
    175 173
                 'key-press-event', self._on_conversation_view_key_press)
    
    176 174
             self.handlers[id_] = self.conversation_view
    
    177 175
     
    
    178
    -        # This is a workaround: as soon as a line break occurs in Gtk.TextView
    
    179
    -        # with word-char wrapping enabled, a hyphen character is automatically
    
    180
    -        # inserted before the line break. This triggers the hscrollbar to show,
    
    181
    -        # see: https://gitlab.gnome.org/GNOME/gtk/-/issues/2384
    
    182
    -        # Using set_hscroll_policy(Gtk.Scrollable.Policy.NEVER) would cause bad
    
    183
    -        # performance during resize, and prevent the window from being shrunk
    
    184
    -        # horizontally under certain conditions (applies to GroupchatControl)
    
    185
    -        hscrollbar = self.xml.conversation_scrolledwindow.get_hscrollbar()
    
    186
    -        hscrollbar.hide()
    
    187
    -
    
    188
    -        self.xml.conversation_scrolledwindow.add(self.conversation_view)
    
    189
    -        self._scrolled_old_upper = None
    
    190
    -        self._scrolled_old_value = None
    
    191
    -
    
    192
    -        self._fetch_start_upper = None
    
    193
    -        self._current_upper = 0
    
    194
    -        self._autoscroll = True
    
    195
    -        self._no_more_messages = False
    
    196
    -
    
    197
    -        vadjustment = self.xml.conversation_scrolledwindow.get_vadjustment()
    
    198
    -
    
    199
    -        vadjustment.connect('notify::upper', self._on_adj_upper_changed)
    
    200
    -        vadjustment.connect('notify::value', self._on_adj_value_changed)
    
    176
    +        self._scrolled_view = ScrolledView()
    
    177
    +        self._scrolled_view.add(self.conversation_view)
    
    178
    +        self.xml.textview_box.add(self._scrolled_view)
    
    179
    +        self.xml.textview_box.reorder_child(self._scrolled_view, 2)
    
    180
    +        self._scrolled_view.connect('request-history',
    
    181
    +                                    self.fetch_n_lines_history, 30)
    
    201 182
     
    
    202 183
             self.msg_textview = MessageInputTextView()
    
    203 184
             self.msg_textview.connect('paste-clipboard',
    
    ... ... @@ -710,7 +691,11 @@ def shutdown(self):
    710 691
                     self.handlers[i].disconnect(i)
    
    711 692
             self.handlers.clear()
    
    712 693
     
    
    694
    +        self.conversation_view.destroy()
    
    695
    +        self._scrolled_view.destroy()
    
    696
    +
    
    713 697
             del self.conversation_view
    
    698
    +        del self._scrolled_view
    
    714 699
             del self.msg_textview
    
    715 700
             del self.msg_scrolledwindow
    
    716 701
     
    
    ... ... @@ -1407,10 +1392,7 @@ def set_control_active(self, state):
    1407 1392
         def scroll_to_end(self, force=False):
    
    1408 1393
             self.conversation_view.scroll_to_end(force)
    
    1409 1394
     
    
    1410
    -    def _on_load_history(self, _button, lines):
    
    1411
    -        self.fetch_n_lines_history(lines)
    
    1412
    -
    
    1413
    -    def fetch_n_lines_history(self, n_lines):
    
    1395
    +    def fetch_n_lines_history(self, _scrolled, n_lines):
    
    1414 1396
             row = self.conversation_view.get_first_message_row()
    
    1415 1397
             if row is None:
    
    1416 1398
                 timestamp = time.time()
    
    ... ... @@ -1431,8 +1413,7 @@ def fetch_n_lines_history(self, n_lines):
    1431 1413
                     n_lines)
    
    1432 1414
     
    
    1433 1415
             if not messages:
    
    1434
    -            self._no_more_messages = True
    
    1435
    -            print('SET NO MORE')
    
    1416
    +            self._scrolled_view.set_history_complete()
    
    1436 1417
                 return
    
    1437 1418
     
    
    1438 1419
             for msg in messages:
    
    ... ... @@ -1471,46 +1452,6 @@ def has_focus(self):
    1471 1452
                         return True
    
    1472 1453
             return False
    
    1473 1454
     
    
    1474
    -    def _on_adj_upper_changed(self, adj, *args):
    
    1475
    -        upper = adj.get_upper()
    
    1476
    -        diff = upper - self._current_upper
    
    1477
    -
    
    1478
    -        if diff != 0:
    
    1479
    -            self._current_upper = upper
    
    1480
    -            if self._autoscroll:
    
    1481
    -                adj.set_value(adj.get_upper() - adj.get_page_size())
    
    1482
    -            else:
    
    1483
    -                # Workaround: https://gitlab.gnome.org/GNOME/gtk/merge_requests/395
    
    1484
    -                self.xml.conversation_scrolledwindow.set_kinetic_scrolling(True)
    
    1485
    -                adj.set_value(adj.get_value() + diff)
    
    1486
    -
    
    1487
    -        if upper == adj.get_page_size():
    
    1488
    -            # There is no scrollbar, load history until there is
    
    1489
    -            self.fetch_n_lines_history(30)
    
    1490
    -
    
    1491
    -    def _on_adj_value_changed(self, adj, *args):
    
    1492
    -        bottom = adj.get_upper() - adj.get_page_size()
    
    1493
    -        if (bottom - adj.get_value()) < 1:
    
    1494
    -            self._autoscroll = True
    
    1495
    -        else:
    
    1496
    -            self._autoscroll = False
    
    1497
    -
    
    1498
    -        if self._no_more_messages:
    
    1499
    -            self._fetch_start_upper = None
    
    1500
    -            return
    
    1501
    -
    
    1502
    -        if self._fetch_start_upper == adj.get_upper():
    
    1503
    -            return
    
    1504
    -
    
    1505
    -        self._fetch_start_upper = None
    
    1506
    -
    
    1507
    -        # Load messages when we are near the top
    
    1508
    -        if adj.get_value() < adj.get_page_size() * 2:
    
    1509
    -            self._fetch_start_upper = adj.get_upper()
    
    1510
    -            # Workaround: https://gitlab.gnome.org/GNOME/gtk/merge_requests/395
    
    1511
    -            self.xml.conversation_scrolledwindow.set_kinetic_scrolling(False)
    
    1512
    -            self.fetch_n_lines_history(30)
    
    1513
    -
    
    1514 1455
         def scroll_messages(self, direction, msg_buf, msg_type):
    
    1515 1456
             if msg_type == 'sent':
    
    1516 1457
                 history = self.sent_history
    

  • gajim/data/gui/chat_control.ui
    ... ... @@ -403,7 +403,7 @@
    403 403
                 <property name="visible">True</property>
    
    404 404
                 <property name="can_focus">True</property>
    
    405 405
                 <child>
    
    406
    -              <object class="GtkBox" id="vbox2">
    
    406
    +              <object class="GtkBox" id="textview_box">
    
    407 407
                     <property name="visible">True</property>
    
    408 408
                     <property name="can_focus">False</property>
    
    409 409
                     <property name="orientation">vertical</property>
    
    ... ... @@ -618,25 +618,7 @@
    618 618
                       </packing>
    
    619 619
                     </child>
    
    620 620
                     <child>
    
    621
    -                  <object class="GtkScrolledWindow" id="conversation_scrolledwindow">
    
    622
    -                    <property name="height_request">60</property>
    
    623
    -                    <property name="can_focus">True</property>
    
    624
    -                    <property name="shadow_type">in</property>
    
    625
    -                    <property name="overlay_scrolling">False</property>
    
    626
    -                    <child>
    
    627
    -                      <placeholder/>
    
    628
    -                    </child>
    
    629
    -                    <style>
    
    630
    -                      <class name="scrolled-no-border"/>
    
    631
    -                      <class name="no-scroll-indicator"/>
    
    632
    -                      <class name="scrollbar-style"/>
    
    633
    -                    </style>
    
    634
    -                  </object>
    
    635
    -                  <packing>
    
    636
    -                    <property name="expand">True</property>
    
    637
    -                    <property name="fill">True</property>
    
    638
    -                    <property name="position">2</property>
    
    639
    -                  </packing>
    
    621
    +                  <placeholder/>
    
    640 622
                     </child>
    
    641 623
                     <child>
    
    642 624
                       <object class="GtkSeparator">
    

  • gajim/data/gui/groupchat_control.ui
    ... ... @@ -143,7 +143,7 @@
    143 143
                     <property name="margin_bottom">7</property>
    
    144 144
                     <property name="spacing">3</property>
    
    145 145
                     <child>
    
    146
    -                  <object class="GtkBox" id="gc_textviews_vbox">
    
    146
    +                  <object class="GtkBox" id="textview_box">
    
    147 147
                         <property name="width_request">0</property>
    
    148 148
                         <property name="visible">True</property>
    
    149 149
                         <property name="can_focus">False</property>
    
    ... ... @@ -256,27 +256,7 @@
    256 256
                           </packing>
    
    257 257
                         </child>
    
    258 258
                         <child>
    
    259
    -                      <object class="GtkScrolledWindow" id="conversation_scrolledwindow">
    
    260
    -                        <property name="width_request">200</property>
    
    261
    -                        <property name="height_request">60</property>
    
    262
    -                        <property name="visible">True</property>
    
    263
    -                        <property name="can_focus">True</property>
    
    264
    -                        <property name="shadow_type">in</property>
    
    265
    -                        <property name="overlay_scrolling">False</property>
    
    266
    -                        <child>
    
    267
    -                          <placeholder/>
    
    268
    -                        </child>
    
    269
    -                        <style>
    
    270
    -                          <class name="scrolled-no-border"/>
    
    271
    -                          <class name="no-scroll-indicator"/>
    
    272
    -                          <class name="scrollbar-style"/>
    
    273
    -                        </style>
    
    274
    -                      </object>
    
    275
    -                      <packing>
    
    276
    -                        <property name="expand">True</property>
    
    277
    -                        <property name="fill">True</property>
    
    278
    -                        <property name="position">2</property>
    
    279
    -                      </packing>
    
    259
    +                      <placeholder/>
    
    280 260
                         </child>
    
    281 261
                         <child>
    
    282 262
                           <object class="GtkSeparator">
    

  • gajim/gtk/conversation/rows/date.py
    ... ... @@ -21,6 +21,10 @@
    21 21
     class DateRow(BaseRow):
    
    22 22
         def __init__(self, account, date_string, timestamp):
    
    23 23
             BaseRow.__init__(self, account)
    
    24
    +
    
    25
    +        self.set_selectable(False)
    
    26
    +        self.set_activatable(False)
    
    27
    +
    
    24 28
             self.type = 'date'
    
    25 29
             self.timestamp = timestamp
    
    26 30
             self.get_style_context().add_class('conversation-date-row')
    

  • gajim/gtk/conversation/rows/scroll_hint.py
    ... ... @@ -24,6 +24,9 @@
    24 24
     class ScrollHintRow(BaseRow):
    
    25 25
         def __init__(self, account, history_mode=False):
    
    26 26
             BaseRow.__init__(self, account)
    
    27
    +        self.set_selectable(False)
    
    28
    +        self.set_activatable(False)
    
    29
    +
    
    27 30
             self.type = 'system'
    
    28 31
             self.timestamp = datetime.fromtimestamp(0)
    
    29 32
     
    
    ... ... @@ -42,11 +45,5 @@ def __init__(self, account, history_mode=False):
    42 45
             self.label.set_text(_('Scroll up to load more chat history…'))
    
    43 46
             self.grid.attach(self.label, 0, 1, 1, 1)
    
    44 47
     
    
    45
    -        self._button = Gtk.Button.new_from_icon_name(
    
    46
    -            'go-up-symbolic', Gtk.IconSize.BUTTON)
    
    47
    -        self._button.set_tooltip_text(_('Load more messages'))
    
    48
    -        self._button.connect('clicked', self._on_load_history)
    
    49
    -        self.grid.attach(self._button, 0, 0, 1, 1)
    
    50
    -
    
    51
    -    def _on_load_history(self, _button):
    
    52
    -        self.get_parent().emit('load-history', 30)
    48
    +    def set_history_complete(self):
    
    49
    +        self.label.set_text(_('There is no more history'))

  • gajim/gtk/conversation/scrolled.py
    1
    +# This file is part of Gajim.
    
    2
    +#
    
    3
    +# Gajim is free software; you can redistribute it and/or modify
    
    4
    +# it under the terms of the GNU General Public License as published
    
    5
    +# by the Free Software Foundation; version 3 only.
    
    6
    +#
    
    7
    +# Gajim is distributed in the hope that it will be useful,
    
    8
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    9
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    
    10
    +# GNU General Public License for more details.
    
    11
    +#
    
    12
    +# You should have received a copy of the GNU General Public License
    
    13
    +# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    14
    +
    
    15
    +from gi.repository import Gtk
    
    16
    +from gi.repository import GObject
    
    17
    +
    
    18
    +
    
    19
    +class ScrolledView(Gtk.ScrolledWindow):
    
    20
    +
    
    21
    +    __gsignals__ = {
    
    22
    +        'request-history': (
    
    23
    +            GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
    
    24
    +            None,
    
    25
    +            ()
    
    26
    +        )
    
    27
    +    }
    
    28
    +
    
    29
    +    def __init__(self, *args, **kwargs):
    
    30
    +        Gtk.ScrolledWindow.__init__(self, *args, **kwargs)
    
    31
    +
    
    32
    +        self.set_overlay_scrolling(False)
    
    33
    +        self.get_style_context().add_class('scrolled-no-border')
    
    34
    +        self.get_style_context().add_class('no-scroll-indicator')
    
    35
    +        self.get_style_context().add_class('scrollbar-style')
    
    36
    +        self.set_shadow_type(Gtk.ShadowType.IN)
    
    37
    +        self.set_vexpand(True)
    
    38
    +
    
    39
    +        self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
    
    40
    +
    
    41
    +        # This is a workaround: as soon as a line break occurs in Gtk.TextView
    
    42
    +        # with word-char wrapping enabled, a hyphen character is automatically
    
    43
    +        # inserted before the line break. This triggers the hscrollbar to show,
    
    44
    +        # see: https://gitlab.gnome.org/GNOME/gtk/-/issues/2384
    
    45
    +        # Using set_hscroll_policy(Gtk.Scrollable.Policy.NEVER) would cause bad
    
    46
    +        # performance during resize, and prevent the window from being shrunk
    
    47
    +        # horizontally under certain conditions (applies to GroupchatControl)
    
    48
    +        self.get_hscrollbar().hide()
    
    49
    +
    
    50
    +        self._current_upper = 0
    
    51
    +        self._autoscroll = True
    
    52
    +        self._request_history_at_upper = None
    
    53
    +        self._complete = False
    
    54
    +
    
    55
    +        vadjustment = self.get_vadjustment()
    
    56
    +        vadjustment.connect('notify::upper', self._on_adj_upper_changed)
    
    57
    +        vadjustment.connect('notify::value', self._on_adj_value_changed)
    
    58
    +
    
    59
    +    @property
    
    60
    +    def autoscroll(self):
    
    61
    +        return self._autoscroll
    
    62
    +
    
    63
    +    def set_history_complete(self):
    
    64
    +        self._complete = True
    
    65
    +        self.get_child().get_child().set_history_complete()
    
    66
    +
    
    67
    +    def _on_adj_upper_changed(self, adj, *args):
    
    68
    +        upper = adj.get_upper()
    
    69
    +        diff = upper - self._current_upper
    
    70
    +
    
    71
    +        if diff != 0:
    
    72
    +            self._current_upper = upper
    
    73
    +            if self._autoscroll:
    
    74
    +                adj.set_value(adj.get_upper() - adj.get_page_size())
    
    75
    +            else:
    
    76
    +                # Workaround
    
    77
    +                # https://gitlab.gnome.org/GNOME/gtk/merge_requests/395
    
    78
    +                self.set_kinetic_scrolling(True)
    
    79
    +                adj.set_value(adj.get_value() + diff)
    
    80
    +
    
    81
    +        if upper == adj.get_page_size():
    
    82
    +            # There is no scrollbar, request history until there is
    
    83
    +            self.emit('request-history')
    
    84
    +
    
    85
    +    def _on_adj_value_changed(self, adj, *args):
    
    86
    +        bottom = adj.get_upper() - adj.get_page_size()
    
    87
    +        if (bottom - adj.get_value()) < 1:
    
    88
    +            self._autoscroll = True
    
    89
    +        else:
    
    90
    +            self._autoscroll = False
    
    91
    +
    
    92
    +        if self._complete:
    
    93
    +            self._request_history_at_upper = None
    
    94
    +            return
    
    95
    +
    
    96
    +        if self._request_history_at_upper == adj.get_upper():
    
    97
    +            # Abort here if we already did a history request and the upper
    
    98
    +            # did not change. This can happen if we scroll very fast and the
    
    99
    +            # value changes while the request has not been fullfilled.
    
    100
    +            return
    
    101
    +
    
    102
    +        self._request_history_at_upper = None
    
    103
    +
    
    104
    +        # Load messages when we are near the top
    
    105
    +        if adj.get_value() < adj.get_page_size() * 2:
    
    106
    +            self._request_history_at_upper = adj.get_upper()
    
    107
    +            # Workaround: https://gitlab.gnome.org/GNOME/gtk/merge_requests/395
    
    108
    +            self.set_kinetic_scrolling(False)
    
    109
    +            self.emit('request-history')

  • gajim/gtk/conversation/view.py
    ... ... @@ -48,11 +48,6 @@ class ConversationView(Gtk.ListBox):
    48 48
                 None,
    
    49 49
                 (str, )
    
    50 50
             ),
    
    51
    -        'load-history': (
    
    52
    -            GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
    
    53
    -            None,
    
    54
    -            (str, )
    
    55
    -        )
    
    56 51
         }
    
    57 52
     
    
    58 53
         def __init__(self, account, contact, history_mode=False):
    
    ... ... @@ -95,7 +90,8 @@ def __init__(self, account, contact, history_mode=False):
    95 90
             self._last_incoming_timestamp = datetime.fromtimestamp(0)
    
    96 91
     
    
    97 92
             # Insert the very first row, containing the scroll hint and load button
    
    98
    -        self.add(ScrollHintRow(self._account, history_mode=self._history_mode))
    
    93
    +        self._scroll_hint_row = ScrollHintRow(self._account)
    
    94
    +        self.add(self._scroll_hint_row)
    
    99 95
             self._timestamps_inserted.append(datetime.fromtimestamp(0))
    
    100 96
     
    
    101 97
         def clear(self):
    
    ... ... @@ -111,6 +107,9 @@ def get_first_message_row(self):
    111 107
                     return row
    
    112 108
             return None
    
    113 109
     
    
    110
    +    def set_history_complete(self):
    
    111
    +        self._scroll_hint_row.set_history_complete()
    
    112
    +
    
    114 113
         def _reset_conversation_view(self):
    
    115 114
             self._first_date = None
    
    116 115
             self._last_date = None