Ticket #1041: gajim-message-mode.patch
| File gajim-message-mode.patch, 113.9 kB (added by David Danier <goliath.mailinglist@…>, 12 months ago) |
|---|
-
src/config.py
==== Patch <gajim-message-mode> level 2 Source: c68c8ed0-6fce-42b2-a3b7-6be8b34235d4:/local:7657 [local] Target: c4d4e39b-2f5f-9a77-1c94-36969bb79148:/trunk:8972 [mirrored] (svn://svn.gajim.org/gajim/trunk) Log: r7653@damasonium: ddanier | 2007-11-14 21:10:55 +0100 r7654@damasonium: ddanier | 2007-11-15 00:32:14 +0100 * Implemented very simple message-mode like psi: - Configuration option for default-type of new messages when clicking on an roster item - SingleMessageWindow: - Added "Next" and "Quote" button - "Next"-button to read next message waiting - "Next"-button show how many messages are waiting (by subscribing to gajim.events) - "Reply"-button does not quote, "Quote"-button does - Focus on Text by default - "RE: " only added to subject if subject is not empty - "Reply"/"Quote" does not close received message window, the parent is closed when reply window is closed and only if there are no more messages waiting r7655@damasonium: ddanier | 2007-11-15 00:33:26 +0100 * TODO for message-mode === src/config.py ==================================================================71 71 self.notebook = self.xml.get_widget('preferences_notebook') 72 72 self.treat_incoming_messages_combobox =\ 73 73 self.xml.get_widget('treat_incoming_messages_combobox') 74 self.send_outgoing_messages_combobox =\ 75 self.xml.get_widget('send_outgoing_messages_combobox') 74 76 self.one_window_type_combobox =\ 75 77 self.xml.get_widget('one_window_type_combobox') 76 78 self.iconset_combobox = self.xml.get_widget('iconset_combobox') … … 140 142 else: 141 143 self.treat_incoming_messages_combobox.set_active(0) 142 144 145 # Set default for send outgoing messages 146 choices = common.config.opt_send_outgoing_messages 147 type = gajim.config.get('send_outgoing_messages') 148 if type in choices: 149 self.send_outgoing_messages_combobox.set_active(choices.index(type)) 150 else: 151 self.send_outgoing_messages_combobox.set_active(0) 152 143 153 # Set default for single window type 144 154 choices = common.config.opt_one_window_types 145 155 type = gajim.config.get('one_message_window') … … 574 584 config_type = common.config.opt_treat_incoming_messages[active] 575 585 gajim.config.set('treat_incoming_messages', config_type) 576 586 587 def on_send_outgoing_messages_combobox_changed(self, widget): 588 active = widget.get_active() 589 config_type = common.config.opt_send_outgoing_messages[active] 590 gajim.config.set('send_outgoing_messages', config_type) 591 577 592 def on_one_window_type_combo_changed(self, widget): 578 593 active = widget.get_active() 579 594 config_type = common.config.opt_one_window_types[active] -
src/roster_window.py
=== src/roster_window.py ==================================================================
1969 1969 self.draw_account(account) 1970 1970 1971 1971 def on_send_single_message_menuitem_activate(self, widget, account, 1972 contact =None):1972 contact=None, resource=None): 1973 1973 if contact is None: 1974 1974 dialogs.SingleMessageWindow(account, action = 'send') 1975 1975 elif type(contact) == type([]): 1976 1976 dialogs.SingleMessageWindow(account, contact, 'send') 1977 1977 else: 1978 1978 jid = contact.jid 1979 if contact.jid == gajim.get_jid_from_account(account): 1979 if resource: 1980 jid += '/' + resource 1981 elif contact.jid == gajim.get_jid_from_account(account): 1980 1982 jid += '/' + contact.resource 1981 1983 dialogs.SingleMessageWindow(account, jid, 'send') 1982 1984 … … 4358 4360 c = gajim.contacts.get_contact_with_highest_priority(account, jid) 4359 4361 if jid == gajim.get_jid_from_account(account): 4360 4362 resource = c.resource 4361 self.on_open_chat_window(widget, c, account, resource = resource, session = session) 4363 send_outgoing_messages = gajim.config.get('send_outgoing_messages') 4364 if send_outgoing_messages == 'normal': 4365 self.on_send_single_message_menuitem_activate(widget, account, c, resource = resource) 4366 else: 4367 self.on_open_chat_window(widget, c, account, resource = resource, session = session) 4362 4368 4363 4369 def on_roster_treeview_row_activated(self, widget, path, col = 0): 4364 4370 '''When an iter is double clicked: open the first event window''' -
src/dialogs.py
=== src/dialogs.py ==================================================================
1841 1841 self.resource = resource 1842 1842 self.session = session 1843 1843 1844 self.next_count = 0 1845 1844 1846 self.xml = gtkgui_helpers.get_glade('single_message_window.glade') 1845 1847 self.window = self.xml.get_widget('single_message_window') 1846 1848 self.count_chars_label = self.xml.get_widget('count_chars_label') … … 1874 1876 self.action = 'form' 1875 1877 1876 1878 self.send_button = self.xml.get_widget('send_button') 1879 self.quote_button = self.xml.get_widget('quote_button') 1877 1880 self.reply_button = self.xml.get_widget('reply_button') 1881 self.next_button = self.xml.get_widget('next_button') 1882 self.next_count_label = self.xml.get_widget('next_count_label') 1878 1883 self.send_and_close_button = self.xml.get_widget('send_and_close_button') 1879 1884 self.cancel_button = self.xml.get_widget('cancel_button') 1880 1885 self.close_button = self.xml.get_widget('close_button') … … 1899 1904 1900 1905 self.prepare_widgets_for(self.action) 1901 1906 1907 gajim.events.event_added_subscribe(self.on_event_added) 1908 gajim.events.event_removed_subscribe(self.on_event_removed) 1909 if self.action == 'receive': 1910 self.update_next_count() 1911 1902 1912 # set_text(None) raises TypeError exception 1903 1913 if self.subject is None: 1904 1914 self.subject = '' … … 1921 1931 1922 1932 if gajim.config.get('saveposition'): 1923 1933 # get window position and size from config 1924 gtkgui_helpers.move_window(self.window, 1925 gajim.config.get('single-msg-x-position'), 1926 gajim.config.get('single-msg-y-position')) 1934 # Makes absolutely no sense when dealing with multiple windows 1935 # (for example when hitting "reply" the orig window stays) 1936 #gtkgui_helpers.move_window(self.window, 1937 # gajim.config.get('single-msg-x-position'), 1938 # gajim.config.get('single-msg-y-position')) 1927 1939 gtkgui_helpers.resize_window(self.window, 1928 1940 gajim.config.get('single-msg-width'), 1929 1941 gajim.config.get('single-msg-height')) … … 1965 1977 self.to_label.show() 1966 1978 self.to_entry.show() 1967 1979 self.reply_button.hide() 1980 self.quote_button.hide() 1981 self.next_button.hide() 1968 1982 self.from_label.hide() 1969 1983 self.from_entry.hide() 1970 1984 self.conversation_scrolledwindow.hide() … … 1979 1993 else: # we write a new message (not from reply) 1980 1994 self.close_button.hide() 1981 1995 if self.to: # do we already have jid? 1982 self.subject_entry.grab_focus() 1996 # Most of the time users skip the subject 1997 #self.subject_entry.grab_focus() 1998 self.message_textview.grab_focus() 1999 else: 2000 self.to_entry.grab_focus() 1983 2001 1984 2002 elif action == 'receive': # prepare UI for Receiving 1985 2003 title = _('Received %s') % title 1986 2004 self.reply_button.show() 2005 self.quote_button.show() 2006 self.next_button.show() 1987 2007 self.from_label.show() 1988 2008 self.from_entry.show() 1989 2009 self.send_button.hide() … … 2004 2024 self.reply_button.grab_focus() 2005 2025 self.cancel_button.hide() 2006 2026 self.close_button.show() 2027 2007 2028 elif action == 'form': # prepare UI for Receiving 2008 2029 title = _('Form %s') % title 2009 2030 self.send_button.show() … … 2018 2039 2019 2040 self.window.set_title(title) 2020 2041 2042 def on_single_message_window_destroy(self, widget): 2043 gajim.events.event_added_unsubscribe(self.on_event_added) 2044 gajim.events.event_removed_unsubscribe(self.on_event_removed) 2045 2046 def update_next_count(self): 2047 # gajim.get_jid_without_resource(self.from_jid)? 2048 self.next_count = len(gajim.events.get_events(self.account, \ 2049 self.from_whom, types=('normal',))) 2050 self.next_count_label.set_label("(%d)" % self.next_count) 2051 2052 def on_event_added(self, event): 2053 if event.type_ == 'normal': 2054 self.update_next_count() 2055 2056 def on_event_removed(self, event_list): 2057 for event in event_list: 2058 if event.type_ == 'normal': 2059 self.update_next_count() 2060 return 2061 2062 def on_next_button_clicked(self, widget): 2063 if self.next_count == 0: 2064 return 2065 next_event = gajim.events.get_first_event(self.account, self.from_whom, 'normal') 2066 #if not next_event: 2067 # next_event = gajim.events.get_first_event(self.account, self.from_whom, 'chat') 2068 if not next_event: 2069 return 2070 # parameters: 2071 # message, subject, kind, time, encrypted, resource, 2072 # msg_id 2073 self.action = 'receive' 2074 self.subject = next_event.parameters[1] 2075 self.message = next_event.parameters[0] 2076 self.resource = next_event.parameters[5] 2077 self.session = next_event.parameters[8] 2078 form_node = next_event.parameters[9] 2079 2080 parent_box = self.xml.get_widget('conversation_scrolledwindow').get_parent() 2081 if form_node: 2082 dataform = dataforms.ExtendForm(node = form_node) 2083 self.form_widget = dataforms_widget.DataFormWidget(dataform) 2084 self.form_widget.show_all() 2085 parent_box.add(self.form_widget) 2086 parent_box.child_set_property(self.form_widget, 'position', 2087 parent_box.child_get_property(self.xml.get_widget('conversation_scrolledwindow'), 'position')) 2088 self.action = 'form' 2089 elif self.form_widget: 2090 self.form_widget.hide() 2091 parent_box.remove(self.form_widget) 2092 self.form_widget = None 2093 2094 self.conversation_textview.clear() 2095 self.prepare_widgets_for(self.action) 2096 2097 # set_text(None) raises TypeError exception 2098 if self.subject is None: 2099 self.subject = '' 2100 self.subject_entry.set_text(self.subject) 2101 2102 gajim.interface.remove_first_event(self.account, self.from_whom, next_event.type_) 2103 self.update_next_count() 2104 2021 2105 def on_cancel_button_clicked(self, widget): 2022 2106 self.save_pos() 2023 2107 self.window.destroy() … … 2073 2157 2074 2158 def on_send_button_clicked(self, widget): 2075 2159 self.send_single_message() 2160 2161 def on_child_window_destroy(self, widget): 2162 # TODO: Only close window if child send a message 2163 if self.next_count == 0: 2164 self.save_pos() 2165 self.window.destroy() 2076 2166 2077 def on_reply_button_clicked(self, widget ):2167 def on_reply_button_clicked(self, widget, quote=False): 2078 2168 # we create a new blank window to send and we preset RE: and to jid 2079 self.subject = _('RE: %s') % self.subject 2080 self.message = _('%s wrote:\n') % self.from_whom + self.message 2081 # add > at the begining of each line 2082 self.message = self.message.replace('\n', '\n> ') + '\n\n' 2083 self.window.destroy() 2084 SingleMessageWindow(self.account, to = self.from_whom, 2085 action = 'send', from_whom = self.from_whom, subject = self.subject, 2086 message = self.message, session = self.session) 2169 if self.subject: 2170 subject = _('RE: %s') % self.subject 2171 else: 2172 subject = '' 2173 if quote: 2174 message = _('%s wrote:\n') % self.from_whom + self.message 2175 # add > at the begining of each line 2176 message = message.replace('\n', '\n> ') + '\n\n' 2177 else: 2178 message = '' 2179 smw = SingleMessageWindow(self.account, to = self.from_whom, 2180 action = 'send', from_whom = self.from_whom, subject = subject, 2181 message = message, session = self.session) 2182 smw.window.connect('destroy', 2183 self.on_child_window_destroy) 2087 2184 2185 def on_quote_button_clicked(self, widget): 2186 self.on_reply_button_clicked(widget, quote=True) 2187 2088 2188 def on_send_and_close_button_clicked(self, widget): 2089 2189 self.send_single_message() 2090 2190 self.save_pos() -
src/common/config.py
=== src/common/config.py ==================================================================
47 47 opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ] 48 48 opt_one_window_types = ['never', 'always', 'peracct', 'pertype'] 49 49 opt_treat_incoming_messages = ['', 'chat', 'normal'] 50 opt_send_outgoing_messages = ['chat', 'normal'] 50 51 51 52 class Config: 52 53 … … 245 246 'use_gnomekeyring': [opt_bool, True, _('If True, Gajim will use Gnome Keyring (if available) to store account passwords.')], 246 247 'show_contacts_number': [opt_bool, True, _('If True, Gajim will show number of online and total contacts in account and group rows.')], 247 248 'treat_incoming_messages': [ opt_str, '', _('Can be empty, \'chat\' or \'normal\'. If not empty, treat all incoming messages as if they were of this type')], 249 'send_outgoing_messages': [ opt_str, 'chat', _('Can be \'chat\' or \'normal\'. All outgoing messages have this type by default.')], 248 250 'scroll_roster_to_last_message': [opt_bool, True, _('If True, Gajim will scroll and select the contact who sent you the last message, if chat window is not already opened.')], 249 251 'use_latex': [opt_bool, False, _('If True, Gajim will convert string between $$ and $$ to an image using dvips and convert before insterting it in chat window.')], 250 252 'change_status_window_timeout': [opt_int, 15, _('Time of inactivity needed before the change status window closes down.')], -
data/glade/single_message_window.glade
=== data/glade/single_message_window.glade ==================================================================
7 7 <property name="default_width">550</property> 8 8 <property name="default_height">280</property> 9 9 <signal name="key_press_event" handler="on_single_message_window_key_press_event"/> 10 <signal name="destroy" handler="on_single_message_window_destroy"/> 10 11 <signal name="delete_event" handler="on_single_message_window_delete_event"/> 11 12 <child> 12 13 <widget class="GtkVBox" id="vbox97"> … … 50 51 <property name="visible">True</property> 51 52 <property name="can_focus">True</property> 52 53 <property name="no_show_all">True</property> 53 <property name="invisible_char">*</property>54 54 </widget> 55 55 <packing> 56 56 <property name="left_attach">1</property> … … 78 78 <widget class="GtkEntry" id="subject_entry"> 79 79 <property name="visible">True</property> 80 80 <property name="can_focus">True</property> 81 <property name="invisible_char">*</property>82 81 </widget> 83 82 <packing> 84 83 <property name="left_attach">1</property> … … 93 92 <property name="visible">True</property> 94 93 <property name="can_focus">True</property> 95 94 <property name="no_show_all">True</property> 96 <property name="invisible_char">*</property>97 95 </widget> 98 96 <packing> 99 97 <property name="left_attach">1</property> … … 236 234 </packing> 237 235 </child> 238 236 <child> 237 <widget class="GtkButton" id="send_and_close_button"> 238 <property name="visible">True</property> 239 <property name="can_focus">True</property> 240 <property name="can_default">True</property> 241 <property name="no_show_all">True</property> 242 <property name="tooltip" translatable="yes">Send message and close window</property> 243 <property name="response_id">0</property> 244 <signal name="clicked" handler="on_send_and_close_button_clicked"/> 245 <child> 246 <widget class="GtkAlignment" id="alignment83"> 247 <property name="visible">True</property> 248 <property name="xscale">0</property> 249 <property name="yscale">0</property> 250 <child> 251 <widget class="GtkHBox" id="hbox2983"> 252 <property name="visible">True</property> 253 <property name="spacing">2</property> 254 <child> 255 <widget class="GtkImage" id="image878"> 256 <property name="visible">True</property> 257 <property name="stock">gtk-ok</property> 258 </widget> 259 <packing> 260 <property name="expand">False</property> 261 <property name="fill">False</property> 262 </packing> 263 </child> 264 <child> 265 <widget class="GtkLabel" id="label347"> 266 <property name="visible">True</property> 267 <property name="label" translatable="yes">_Send & Close</property> 268 <property name="use_underline">True</property> 269 </widget> 270 <packing> 271 <property name="expand">False</property> 272 <property name="fill">False</property> 273 <property name="position">1</property> 274 </packing> 275 </child> 276 </widget> 277 </child> 278 </widget> 279 </child> 280 </widget> 281 <packing> 282 <property name="position">3</property> 283 </packing> 284 </child> 285 <child> 286 <widget class="GtkButton" id="quote_button"> 287 <property name="visible">True</property> 288 <property name="can_focus">True</property> 289 <property name="can_default">True</property> 290 <property name="no_show_all">True</property> 291 <property name="tooltip" translatable="yes">Reply to this message</property> 292 <property name="response_id">0</property> 293 <signal name="clicked" handler="on_quote_button_clicked"/> 294 <child> 295 <widget class="GtkAlignment" id="alignment3"> 296 <property name="visible">True</property> 297 <property name="xscale">0</property> 298 <property name="yscale">0</property> 299 <child> 300 <widget class="GtkHBox" id="hbox3"> 301 <property name="visible">True</property> 302 <property name="spacing">2</property> 303 <child> 304 <widget class="GtkImage" id="image3"> 305 <property name="visible">True</property> 306 <property name="stock">gtk-ok</property> 307 </widget> 308 <packing> 309 <property name="expand">False</property> 310 <property name="fill">False</property> 311 </packing> 312 </child> 313 <child> 314 <widget class="GtkLabel" id="label3"> 315 <property name="visible">True</property> 316 <property name="label" translatable="yes">_Quote</property> 317 <property name="use_underline">True</property> 318 </widget> 319 <packing> 320 <property name="expand">False</property> 321 <property name="fill">False</property> 322 <property name="position">1</property> 323 </packing> 324 </child> 325 </widget> 326 </child> 327 </widget> 328 </child> 329 </widget> 330 <packing> 331 <property name="position">4</property> 332 </packing> 333 </child> 334 <child> 239 335 <widget class="GtkButton" id="reply_button"> 240 336 <property name="visible">True</property> 241 337 <property name="can_focus">True</property> … … 281 377 </child> 282 378 </widget> 283 379 <packing> 284 <property name="position"> 3</property>380 <property name="position">5</property> 285 381 </packing> 286 382 </child> 287 383 <child> 288 <widget class="GtkButton" id=" send_and_close_button">384 <widget class="GtkButton" id="next_button"> 289 385 <property name="visible">True</property> 290 386 <property name="can_focus">True</property> 291 387 <property name="can_default">True</property> 292 388 <property name="no_show_all">True</property> 293 <property name="tooltip" translatable="yes"> Send message and close window</property>389 <property name="tooltip" translatable="yes">View next message</property> 294 390 <property name="response_id">0</property> 295 <signal name="clicked" handler="on_ send_and_close_button_clicked"/>391 <signal name="clicked" handler="on_next_button_clicked"/> 296 392 <child> 297 <widget class="GtkAlignment" id="alignment 83">393 <widget class="GtkAlignment" id="alignment5"> 298 394 <property name="visible">True</property> 299 395 <property name="xscale">0</property> 300 396 <property name="yscale">0</property> 301 397 <child> 302 <widget class="GtkHBox" id="hbox 2983">398 <widget class="GtkHBox" id="hbox5"> 303 399 <property name="visible">True</property> 304 400 <property name="spacing">2</property> 305 401 <child> 306 <widget class="GtkImage" id="image 878">402 <widget class="GtkImage" id="image5"> 307 403 <property name="visible">True</property> 308 <property name="stock">gtk- ok</property>404 <property name="stock">gtk-media-next</property> 309 405 </widget> 310 406 <packing> 311 407 <property name="expand">False</property> … … 313 409 </packing> 314 410 </child> 315 411 <child> 316 <widget class="Gtk Label" id="label347">412 <widget class="GtkHBox" id="hbox1"> 317 413 <property name="visible">True</property> 318 <property name="label" translatable="yes">_Send & Close</property> 319 <property name="use_underline">True</property> 414 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 415 <property name="spacing">4</property> 416 <child> 417 <widget class="GtkLabel" id="label5"> 418 <property name="visible">True</property> 419 <property name="label" translatable="yes">_Next</property> 420 <property name="use_underline">True</property> 421 </widget> 422 <packing> 423 <property name="expand">False</property> 424 <property name="fill">False</property> 425 </packing> 426 </child> 427 <child> 428 <widget class="GtkLabel" id="next_count_label"> 429 <property name="visible">True</property> 430 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 431 <property name="label" translatable="yes">(0)</property> 432 </widget> 433 <packing> 434 <property name="position">1</property> 435 </packing> 436 </child> 320 437 </widget> 321 438 <packing> 322 439 <property name="expand">False</property> … … 330 447 </child> 331 448 </widget> 332 449 <packing> 333 <property name="position"> 4</property>450 <property name="position">6</property> 334 451 </packing> 335 452 </child> 336 453 </widget> -
data/glade/preferences_window.glade
=== data/glade/preferences_window.glade ==================================================================
26 26 <widget class="GtkFrame" id="frame1"> 27 27 <property name="visible">True</property> 28 28 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 29 <property name="label_xalign">0</property>30 29 <property name="shadow_type">GTK_SHADOW_NONE</property> 31 30 <child> 32 31 <widget class="GtkAlignment" id="alignment1"> … … 111 110 <widget class="GtkFrame" id="frame2"> 112 111 <property name="visible">True</property> 113 112 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 114 <property name="label_xalign">0</property>115 113 <property name="shadow_type">GTK_SHADOW_NONE</property> 116 114 <child> 117 115 <widget class="GtkAlignment" id="alignment2"> … … 122 120 <widget class="GtkTable" id="table1"> 123 121 <property name="visible">True</property> 124 122 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 125 <property name="n_rows"> 6</property>123 <property name="n_rows">7</property> 126 124
