Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
3f38ccc3
by Philipp Hörist at 2017-03-11T22:11:00+01:00
-
1e06db9f
by Philipp Hörist at 2017-03-11T22:11:01+01:00
-
8547d2b4
by Philipp Hörist at 2017-03-11T22:11:02+01:00
-
55561b3d
by Philipp Hörist at 2017-03-11T22:18:37+01:00
5 changed files:
- src/chat_control.py
- src/chat_control_base.py
- src/common/config.py
- src/conversation_textview.py
- src/gui_interface.py
Changes:
| ... | ... | @@ -39,6 +39,7 @@ import gui_menu_builder |
| 39 | 39 |
import message_control
|
| 40 | 40 |
import dialogs
|
| 41 | 41 |
|
| 42 |
+from common import logger
|
|
| 42 | 43 |
from common import gajim
|
| 43 | 44 |
from common import helpers
|
| 44 | 45 |
from common import exceptions
|
| ... | ... | @@ -1626,10 +1627,9 @@ class ChatControl(ChatControlBase): |
| 1626 | 1627 |
rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many,
|
| 1627 | 1628 |
pending_how_many, timeout, self.account)
|
| 1628 | 1629 |
except exceptions.DatabaseMalformed:
|
| 1629 |
- import common.logger
|
|
| 1630 | 1630 |
dialogs.ErrorDialog(_('Database Error'),
|
| 1631 | 1631 |
_('The database file (%s) cannot be read. Try to repair it or '
|
| 1632 |
- 'remove it (all history will be lost).') % common.logger.LOG_DB_PATH)
|
|
| 1632 |
+ 'remove it (all history will be lost).') % logger.LOG_DB_PATH)
|
|
| 1633 | 1633 |
rows = []
|
| 1634 | 1634 |
local_old_kind = None
|
| 1635 | 1635 |
self.conv_textview.just_cleared = True
|
| ... | ... | @@ -323,7 +323,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): |
| 323 | 323 |
id_ = widget.connect('changed',
|
| 324 | 324 |
self.on_conversation_vadjustment_changed)
|
| 325 | 325 |
self.handlers[id_] = widget
|
| 326 |
- self.scroll_to_end_id = None
|
|
| 327 | 326 |
self.was_at_the_end = True
|
| 328 | 327 |
self.correcting = False
|
| 329 | 328 |
self.last_sent_msg = None
|
| ... | ... | @@ -984,27 +983,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): |
| 984 | 983 |
# There were events to remove
|
| 985 | 984 |
self.redraw_after_event_removed(jid)
|
| 986 | 985 |
|
| 987 |
- def bring_scroll_to_end(self, textview, diff_y=0):
|
|
| 988 |
- """
|
|
| 989 |
- Scroll to the end of textview if end is not visible
|
|
| 990 |
- """
|
|
| 991 |
- if self.scroll_to_end_id:
|
|
| 992 |
- # a scroll is already planned
|
|
| 993 |
- return
|
|
| 994 |
- buffer_ = textview.get_buffer()
|
|
| 995 |
- end_iter = buffer_.get_end_iter()
|
|
| 996 |
- end_rect = textview.get_iter_location(end_iter)
|
|
| 997 |
- visible_rect = textview.get_visible_rect()
|
|
| 998 |
- # scroll only if expected end is not visible
|
|
| 999 |
- if end_rect.y >= (visible_rect.y + visible_rect.height + diff_y):
|
|
| 1000 |
- self.scroll_to_end_id = GLib.idle_add(self.scroll_to_end_iter,
|
|
| 1001 |
- textview)
|
|
| 1002 |
- |
|
| 1003 |
- def scroll_to_end_iter(self, textview):
|
|
| 1004 |
- buffer_ = textview.get_buffer()
|
|
| 1005 |
- end_iter = buffer_.get_end_iter()
|
|
| 1006 |
- textview.scroll_to_iter(end_iter, 0, False, 1, 1)
|
|
| 1007 |
- self.scroll_to_end_id = None
|
|
| 986 |
+ def scroll_to_end_iter(self):
|
|
| 987 |
+ self.conv_textview.scroll_to_end_iter()
|
|
| 1008 | 988 |
return False
|
| 1009 | 989 |
|
| 1010 | 990 |
def on_configure_event(self, msg_textview, event):
|
| ... | ... | @@ -1065,18 +1045,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): |
| 1065 | 1045 |
# used to stay at the end of the textview when we shrink conversation
|
| 1066 | 1046 |
# textview.
|
| 1067 | 1047 |
if self.was_at_the_end:
|
| 1068 |
- if self.conv_textview.at_the_end():
|
|
| 1069 |
- # we are at the end
|
|
| 1070 |
- self.conv_textview.bring_scroll_to_end(-18)
|
|
| 1071 |
- else:
|
|
| 1072 |
- self.conv_textview.bring_scroll_to_end(-18, use_smooth=False)
|
|
| 1048 |
+ self.scroll_to_end_iter()
|
|
| 1073 | 1049 |
self.was_at_the_end = (adjustment.get_upper() - adjustment.get_value()\
|
| 1074 | 1050 |
- adjustment.get_page_size()) < 18
|
| 1075 | 1051 |
|
| 1076 | 1052 |
def on_conversation_vadjustment_value_changed(self, adjustment):
|
| 1077 |
- # stop automatic scroll when we manually scroll
|
|
| 1078 |
- if not self.conv_textview.auto_scrolling:
|
|
| 1079 |
- self.conv_textview.stop_scrolling()
|
|
| 1080 | 1053 |
self.was_at_the_end = (adjustment.get_upper() - adjustment.get_value() \
|
| 1081 | 1054 |
- adjustment.get_page_size()) < 18
|
| 1082 | 1055 |
if self.resource:
|
| ... | ... | @@ -279,7 +279,6 @@ class Config: |
| 279 | 279 |
'hide_groupchat_occupants_list': [opt_bool, False, _('Hides the group chat occupants list in group chat window.')],
|
| 280 | 280 |
'chat_merge_consecutive_nickname': [opt_bool, False, _('In a chat, show the nickname at the beginning of a line only when it\'s not the same person talking than in previous message.')],
|
| 281 | 281 |
'chat_merge_consecutive_nickname_indent': [opt_str, ' ', _('Indentation when using merge consecutive nickname.')],
|
| 282 |
- 'use_smooth_scrolling': [opt_bool, True, _('Smooth scroll message in conversation window')],
|
|
| 283 | 282 |
'gc_nicknames_colors': [ opt_str, '#4e9a06:#f57900:#ce5c00:#3465a4:#204a87:#75507b:#5c3566:#c17d11:#8f5902:#ef2929:#cc0000:#a40000', _('List of colors, separated by ":", that will be used to color nicknames in group chats.'), True ],
|
| 284 | 283 |
'ctrl_tab_go_to_next_composing': [opt_bool, True, _('Ctrl-Tab go to next composing tab when none is unread.')],
|
| 285 | 284 |
'confirm_metacontacts': [ opt_str, '', _('Should we show the confirm metacontacts creation dialog or not? Empty string means we never show the dialog.')],
|
| ... | ... | @@ -216,9 +216,6 @@ class ConversationTextview(GObject.GObject): |
| 216 | 216 |
# last_received_message_id[name] = (msg_stanza_id, line_start_mark)
|
| 217 | 217 |
self.last_received_message_id = {}
|
| 218 | 218 |
|
| 219 |
- # It's True when we scroll in the code, so we can detect scroll from user
|
|
| 220 |
- self.auto_scrolling = False
|
|
| 221 |
- |
|
| 222 | 219 |
# connect signals
|
| 223 | 220 |
id_ = self.tv.connect('populate_popup', self.on_textview_populate_popup)
|
| 224 | 221 |
self.handlers[id_] = self.tv
|
| ... | ... | @@ -325,7 +322,6 @@ class ConversationTextview(GObject.GObject): |
| 325 | 322 |
# holds a mark at the end of --- line
|
| 326 | 323 |
self.focus_out_end_mark = None
|
| 327 | 324 |
|
| 328 |
- self.smooth_id = None
|
|
| 329 | 325 |
self.just_cleared = False
|
| 330 | 326 |
|
| 331 | 327 |
def query_tooltip(self, widget, x_pos, y_pos, keyboard_mode, tooltip):
|
| ... | ... | @@ -398,87 +394,7 @@ class ConversationTextview(GObject.GObject): |
| 398 | 394 |
self.tv.tagSthAtSth.set_property('foreground', color)
|
| 399 | 395 |
|
| 400 | 396 |
def at_the_end(self):
|
| 401 |
- buffer_ = self.tv.get_buffer()
|
|
| 402 |
- end_iter = buffer_.get_end_iter()
|
|
| 403 |
- end_rect = self.tv.get_iter_location(end_iter)
|
|
| 404 |
- visible_rect = self.tv.get_visible_rect()
|
|
| 405 |
- if end_rect.y <= (visible_rect.y + visible_rect.height):
|
|
| 406 |
- return True
|
|
| 407 |
- return False
|
|
| 408 |
- |
|
| 409 |
- # Smooth scrolling inspired by Pidgin code
|
|
| 410 |
- def smooth_scroll(self):
|
|
| 411 |
- parent = self.tv.get_parent()
|
|
| 412 |
- if not parent:
|
|
| 413 |
- return False
|
|
| 414 |
- vadj = parent.get_vadjustment()
|
|
| 415 |
- max_val = vadj.get_upper() - vadj.get_page_size() + 1
|
|
| 416 |
- cur_val = vadj.get_value()
|
|
| 417 |
- # scroll by 1/3rd of remaining distance
|
|
| 418 |
- onethird = cur_val + ((max_val - cur_val) / 3.0)
|
|
| 419 |
- self.auto_scrolling = True
|
|
| 420 |
- vadj.set_value(onethird)
|
|
| 421 |
- self.auto_scrolling = False
|
|
| 422 |
- if max_val - onethird < 0.01:
|
|
| 423 |
- self.smooth_id = None
|
|
| 424 |
- self.smooth_scroll_timer.cancel()
|
|
| 425 |
- return False
|
|
| 426 |
- return True
|
|
| 427 |
- |
|
| 428 |
- def smooth_scroll_timeout(self):
|
|
| 429 |
- GLib.idle_add(self.do_smooth_scroll_timeout)
|
|
| 430 |
- return
|
|
| 431 |
- |
|
| 432 |
- def do_smooth_scroll_timeout(self):
|
|
| 433 |
- if not self.smooth_id:
|
|
| 434 |
- # we finished scrolling
|
|
| 435 |
- return
|
|
| 436 |
- GLib.source_remove(self.smooth_id)
|
|
| 437 |
- self.smooth_id = None
|
|
| 438 |
- parent = self.tv.get_parent()
|
|
| 439 |
- if parent:
|
|
| 440 |
- vadj = parent.get_vadjustment()
|
|
| 441 |
- self.auto_scrolling = True
|
|
| 442 |
- vadj.set_value(vadj.get_upper() - vadj.get_page_size() + 1)
|
|
| 443 |
- self.auto_scrolling = False
|
|
| 444 |
- |
|
| 445 |
- def smooth_scroll_to_end(self):
|
|
| 446 |
- if self.smooth_id is not None: # already scrolling
|
|
| 447 |
- return False
|
|
| 448 |
- self.smooth_id = GLib.timeout_add(self.SCROLL_DELAY,
|
|
| 449 |
- self.smooth_scroll)
|
|
| 450 |
- self.smooth_scroll_timer = Timer(self.MAX_SCROLL_TIME,
|
|
| 451 |
- self.smooth_scroll_timeout)
|
|
| 452 |
- self.smooth_scroll_timer.start()
|
|
| 453 |
- return False
|
|
| 454 |
- |
|
| 455 |
- def scroll_to_end(self):
|
|
| 456 |
- parent = self.tv.get_parent()
|
|
| 457 |
- buffer_ = self.tv.get_buffer()
|
|
| 458 |
- end_mark = buffer_.get_mark('end')
|
|
| 459 |
- if not end_mark:
|
|
| 460 |
- return False
|
|
| 461 |
- self.auto_scrolling = True
|
|
| 462 |
- self.tv.scroll_to_mark(end_mark, 0, True, 0, 1)
|
|
| 463 |
- adjustment = parent.get_hadjustment()
|
|
| 464 |
- adjustment.set_value(0)
|
|
| 465 |
- self.auto_scrolling = False
|
|
| 466 |
- return False # when called in an idle_add, just do it once
|
|
| 467 |
- |
|
| 468 |
- def bring_scroll_to_end(self, diff_y=0, use_smooth=None):
|
|
| 469 |
- ''' scrolls to the end of textview if end is not visible '''
|
|
| 470 |
- if use_smooth is None:
|
|
| 471 |
- use_smooth = gajim.config.get('use_smooth_scrolling')
|
|
| 472 |
- buffer_ = self.tv.get_buffer()
|
|
| 473 |
- end_iter = buffer_.get_end_iter()
|
|
| 474 |
- end_rect = self.tv.get_iter_location(end_iter)
|
|
| 475 |
- visible_rect = self.tv.get_visible_rect()
|
|
| 476 |
- # scroll only if expected end is not visible
|
|
| 477 |
- if end_rect.y >= (visible_rect.y + visible_rect.height + diff_y):
|
|
| 478 |
- if use_smooth:
|
|
| 479 |
- GLib.idle_add(self.smooth_scroll_to_end)
|
|
| 480 |
- else:
|
|
| 481 |
- GLib.idle_add(self.scroll_to_end_iter)
|
|
| 397 |
+ return gtkgui_helpers.at_the_end(self.tv.get_parent())
|
|
| 482 | 398 |
|
| 483 | 399 |
def scroll_to_end_iter(self):
|
| 484 | 400 |
buffer_ = self.tv.get_buffer()
|
| ... | ... | @@ -488,12 +404,6 @@ class ConversationTextview(GObject.GObject): |
| 488 | 404 |
self.tv.scroll_to_iter(end_iter, 0, False, 1, 1)
|
| 489 | 405 |
return False # when called in an idle_add, just do it once
|
| 490 | 406 |
|
| 491 |
- def stop_scrolling(self):
|
|
| 492 |
- if self.smooth_id:
|
|
| 493 |
- GLib.source_remove(self.smooth_id)
|
|
| 494 |
- self.smooth_id = None
|
|
| 495 |
- self.smooth_scroll_timer.cancel()
|
|
| 496 |
- |
|
| 497 | 407 |
def correct_message(self, correct_id, kind, name):
|
| 498 | 408 |
allowed = True
|
| 499 | 409 |
if kind == 'incoming':
|
| ... | ... | @@ -649,7 +559,7 @@ class ConversationTextview(GObject.GObject): |
| 649 | 559 |
if scroll:
|
| 650 | 560 |
# scroll to the end (via idle in case the scrollbar has
|
| 651 | 561 |
# appeared)
|
| 652 |
- GLib.idle_add(self.scroll_to_end)
|
|
| 562 |
+ GLib.idle_add(self.scroll_to_end_iter)
|
|
| 653 | 563 |
|
| 654 | 564 |
def on_textview_draw(self, widget, ctx):
|
| 655 | 565 |
return
|
| ... | ... | @@ -1283,8 +1193,6 @@ class ConversationTextview(GObject.GObject): |
| 1283 | 1193 |
# even if we insert directly at the mark iter
|
| 1284 | 1194 |
temp_mark = buffer_.create_mark('temp', iter_, left_gravity=True)
|
| 1285 | 1195 |
|
| 1286 |
- at_the_end = self.at_the_end()
|
|
| 1287 |
- |
|
| 1288 | 1196 |
if text.startswith('/me '):
|
| 1289 | 1197 |
direction_mark = i18n.paragraph_direction_mark(str(text[3:]))
|
| 1290 | 1198 |
else:
|
| ... | ... | @@ -1369,13 +1277,9 @@ class ConversationTextview(GObject.GObject): |
| 1369 | 1277 |
self.last_sent_message_id = (msg_stanza_id, new_mark)
|
| 1370 | 1278 |
|
| 1371 | 1279 |
if not insert_mark:
|
| 1372 |
- if at_the_end or kind == 'outgoing':
|
|
| 1280 |
+ if self.at_the_end() or kind == 'outgoing':
|
|
| 1373 | 1281 |
# we are at the end or we are sending something
|
| 1374 |
- # scroll to the end (via idle in case the scrollbar has appeared)
|
|
| 1375 |
- if gajim.config.get('use_smooth_scrolling'):
|
|
| 1376 |
- GLib.idle_add(self.smooth_scroll_to_end)
|
|
| 1377 |
- else:
|
|
| 1378 |
- GLib.idle_add(self.scroll_to_end)
|
|
| 1282 |
+ GLib.idle_add(self.scroll_to_end_iter)
|
|
| 1379 | 1283 |
|
| 1380 | 1284 |
self.just_cleared = False
|
| 1381 | 1285 |
buffer_.end_user_action()
|
| ... | ... | @@ -1831,7 +1831,7 @@ class Interface: |
| 1831 | 1831 |
# Using isinstance here because we want to catch all derived types
|
| 1832 | 1832 |
if isinstance(ctrl, ChatControlBase):
|
| 1833 | 1833 |
tv = ctrl.conv_textview
|
| 1834 |
- tv.scroll_to_end()
|
|
| 1834 |
+ tv.scroll_to_end_iter()
|
|
| 1835 | 1835 |
|
| 1836 | 1836 |
################################################################################
|
| 1837 | 1837 |
### Methods dealing with emoticons
|