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

Commits:

2 changed files:

Changes:

  • gajim/data/gui/single_message_window.ui
    1 1
     <?xml version="1.0" encoding="UTF-8"?>
    
    2
    -<!-- Generated with glade 3.18.3 -->
    
    2
    +<!-- Generated with glade 3.22.1 -->
    
    3 3
     <interface>
    
    4
    -  <requires lib="gtk+" version="3.12"/>
    
    4
    +  <requires lib="gtk+" version="3.20"/>
    
    5 5
       <object class="GtkImage" id="image1">
    
    6 6
         <property name="visible">True</property>
    
    7 7
         <property name="can_focus">False</property>
    
    8
    -    <property name="stock">gtk-ok</property>
    
    8
    +    <property name="icon_name">mail-reply-sender-symbolic</property>
    
    9 9
       </object>
    
    10 10
       <object class="GtkImage" id="image2">
    
    11 11
         <property name="visible">True</property>
    
    12 12
         <property name="can_focus">False</property>
    
    13
    -    <property name="stock">gtk-ok</property>
    
    13
    +    <property name="icon_name">mail-send-symbolic</property>
    
    14 14
       </object>
    
    15 15
       <object class="GtkImage" id="image3">
    
    16 16
         <property name="visible">True</property>
    
    17 17
         <property name="can_focus">False</property>
    
    18
    -    <property name="stock">gtk-jump-to</property>
    
    18
    +    <property name="icon_name">mail-send-symbolic</property>
    
    19
    +  </object>
    
    20
    +  <object class="GtkImage" id="image4">
    
    21
    +    <property name="visible">True</property>
    
    22
    +    <property name="can_focus">False</property>
    
    23
    +    <property name="icon_name">user-info-symbolic</property>
    
    19 24
       </object>
    
    20 25
       <object class="GtkWindow" id="single_message_window">
    
    21 26
         <property name="can_focus">False</property>
    
    22
    -    <property name="border_width">6</property>
    
    23
    -    <property name="default_width">550</property>
    
    24
    -    <property name="default_height">280</property>
    
    25 27
         <signal name="delete-event" handler="on_single_message_window_delete_event" swapped="no"/>
    
    26 28
         <signal name="destroy" handler="on_single_message_window_destroy" swapped="no"/>
    
    27 29
         <signal name="key-press-event" handler="on_single_message_window_key_press_event" swapped="no"/>
    
    28 30
         <child>
    
    29
    -      <object class="GtkBox" id="vbox97">
    
    31
    +      <placeholder/>
    
    32
    +    </child>
    
    33
    +    <child>
    
    34
    +      <object class="GtkBox">
    
    30 35
             <property name="visible">True</property>
    
    31 36
             <property name="can_focus">False</property>
    
    37
    +        <property name="border_width">18</property>
    
    32 38
             <property name="orientation">vertical</property>
    
    33
    -        <property name="spacing">6</property>
    
    34 39
             <child>
    
    35
    -          <object class="GtkGrid" id="grid1">
    
    40
    +          <object class="GtkGrid" id="send_grid">
    
    36 41
                 <property name="visible">True</property>
    
    37 42
                 <property name="can_focus">False</property>
    
    38
    -            <property name="row_spacing">3</property>
    
    39
    -            <property name="column_spacing">3</property>
    
    43
    +            <property name="no_show_all">True</property>
    
    44
    +            <property name="row_spacing">6</property>
    
    45
    +            <property name="column_spacing">12</property>
    
    40 46
                 <child>
    
    41
    -              <object class="GtkLabel" id="from_label">
    
    47
    +              <object class="GtkLabel" id="to_label">
    
    42 48
                     <property name="visible">True</property>
    
    43 49
                     <property name="can_focus">False</property>
    
    44
    -                <property name="no_show_all">True</property>
    
    45
    -                <property name="xalign">0</property>
    
    46
    -                <property name="label" translatable="yes">From:</property>
    
    50
    +                <property name="halign">end</property>
    
    51
    +                <property name="label" translatable="yes">_To</property>
    
    52
    +                <property name="use_underline">True</property>
    
    53
    +                <property name="mnemonic_widget">to_entry</property>
    
    54
    +                <style>
    
    55
    +                  <class name="dim-label"/>
    
    56
    +                </style>
    
    47 57
                   </object>
    
    48 58
                   <packing>
    
    49 59
                     <property name="left_attach">0</property>
    
    ... ... @@ -51,124 +61,239 @@
    51 61
                   </packing>
    
    52 62
                 </child>
    
    53 63
                 <child>
    
    54
    -              <object class="GtkLabel" id="to_label">
    
    64
    +              <object class="GtkEntry" id="to_entry">
    
    55 65
                     <property name="visible">True</property>
    
    56
    -                <property name="can_focus">False</property>
    
    57
    -                <property name="no_show_all">True</property>
    
    58
    -                <property name="xalign">0</property>
    
    59
    -                <property name="label" translatable="yes">To:</property>
    
    66
    +                <property name="can_focus">True</property>
    
    67
    +                <property name="hexpand">True</property>
    
    68
    +                <property name="placeholder_text" translatable="yes">user@example.org</property>
    
    60 69
                   </object>
    
    61 70
                   <packing>
    
    62
    -                <property name="left_attach">0</property>
    
    63
    -                <property name="top_attach">1</property>
    
    71
    +                <property name="left_attach">1</property>
    
    72
    +                <property name="top_attach">0</property>
    
    64 73
                   </packing>
    
    65 74
                 </child>
    
    66 75
                 <child>
    
    67
    -              <object class="GtkLabel" id="label335">
    
    76
    +              <object class="GtkLabel" id="subject_label">
    
    68 77
                     <property name="visible">True</property>
    
    69 78
                     <property name="can_focus">False</property>
    
    70
    -                <property name="label" translatable="yes">Subject:</property>
    
    79
    +                <property name="halign">end</property>
    
    80
    +                <property name="label" translatable="yes">Su_bject</property>
    
    81
    +                <property name="use_underline">True</property>
    
    82
    +                <property name="mnemonic_widget">subject_entry</property>
    
    83
    +                <property name="single_line_mode">True</property>
    
    84
    +                <style>
    
    85
    +                  <class name="dim-label"/>
    
    86
    +                </style>
    
    71 87
                   </object>
    
    72 88
                   <packing>
    
    73 89
                     <property name="left_attach">0</property>
    
    74
    -                <property name="top_attach">2</property>
    
    90
    +                <property name="top_attach">1</property>
    
    75 91
                   </packing>
    
    76 92
                 </child>
    
    77 93
                 <child>
    
    78
    -              <object class="GtkEntry" id="from_entry">
    
    94
    +              <object class="GtkEntry" id="subject_entry">
    
    79 95
                     <property name="visible">True</property>
    
    80 96
                     <property name="can_focus">True</property>
    
    81
    -                <property name="no_show_all">True</property>
    
    82
    -                <property name="hexpand">True</property>
    
    97
    +                <property name="placeholder_text" translatable="yes">Type the subject here...</property>
    
    98
    +                <property name="show_emoji_icon">True</property>
    
    83 99
                   </object>
    
    84 100
                   <packing>
    
    85 101
                     <property name="left_attach">1</property>
    
    86
    -                <property name="top_attach">0</property>
    
    102
    +                <property name="top_attach">1</property>
    
    87 103
                     <property name="width">2</property>
    
    88 104
                   </packing>
    
    89 105
                 </child>
    
    90 106
                 <child>
    
    91
    -              <object class="GtkEntry" id="to_entry">
    
    107
    +              <object class="GtkLabel" id="message_label_send">
    
    92 108
                     <property name="visible">True</property>
    
    93
    -                <property name="can_focus">True</property>
    
    94
    -                <property name="no_show_all">True</property>
    
    95
    -                <property name="hexpand">True</property>
    
    109
    +                <property name="can_focus">False</property>
    
    110
    +                <property name="halign">end</property>
    
    111
    +                <property name="label" translatable="yes">_Message</property>
    
    112
    +                <property name="use_underline">True</property>
    
    113
    +                <property name="mnemonic_widget">message_textview</property>
    
    114
    +                <style>
    
    115
    +                  <class name="dim-label"/>
    
    116
    +                </style>
    
    96 117
                   </object>
    
    97 118
                   <packing>
    
    98
    -                <property name="left_attach">1</property>
    
    99
    -                <property name="top_attach">1</property>
    
    100
    -                <property name="width">2</property>
    
    119
    +                <property name="left_attach">0</property>
    
    120
    +                <property name="top_attach">2</property>
    
    101 121
                   </packing>
    
    102 122
                 </child>
    
    103 123
                 <child>
    
    104
    -              <object class="GtkEntry" id="subject_entry">
    
    124
    +              <object class="GtkScrolledWindow" id="message_scrolledwindow">
    
    125
    +                <property name="height_request">100</property>
    
    105 126
                     <property name="visible">True</property>
    
    106 127
                     <property name="can_focus">True</property>
    
    107
    -                <property name="hexpand">True</property>
    
    128
    +                <property name="vexpand">True</property>
    
    129
    +                <property name="shadow_type">in</property>
    
    130
    +                <child>
    
    131
    +                  <object class="GtkTextView" id="message_textview">
    
    132
    +                    <property name="visible">True</property>
    
    133
    +                    <property name="can_focus">True</property>
    
    134
    +                    <property name="wrap_mode">word-char</property>
    
    135
    +                    <property name="left_margin">6</property>
    
    136
    +                    <property name="right_margin">6</property>
    
    137
    +                    <property name="top_margin">6</property>
    
    138
    +                    <property name="bottom_margin">6</property>
    
    139
    +                  </object>
    
    140
    +                </child>
    
    108 141
                   </object>
    
    109 142
                   <packing>
    
    110 143
                     <property name="left_attach">1</property>
    
    111 144
                     <property name="top_attach">2</property>
    
    145
    +                <property name="width">2</property>
    
    112 146
                   </packing>
    
    113 147
                 </child>
    
    114 148
                 <child>
    
    115 149
                   <object class="GtkLabel" id="count_chars_label">
    
    116 150
                     <property name="visible">True</property>
    
    117 151
                     <property name="can_focus">False</property>
    
    118
    -                <property name="label" translatable="yes">0</property>
    
    152
    +                <property name="halign">end</property>
    
    153
    +                <property name="label" translatable="yes">Characters typed: 0</property>
    
    154
    +                <style>
    
    155
    +                  <class name="dim-label"/>
    
    156
    +                </style>
    
    157
    +              </object>
    
    158
    +              <packing>
    
    159
    +                <property name="left_attach">0</property>
    
    160
    +                <property name="top_attach">3</property>
    
    161
    +                <property name="width">3</property>
    
    162
    +              </packing>
    
    163
    +            </child>
    
    164
    +            <child>
    
    165
    +              <object class="GtkButton" id="show_contact_info_button">
    
    166
    +                <property name="visible">True</property>
    
    167
    +                <property name="sensitive">False</property>
    
    168
    +                <property name="can_focus">True</property>
    
    169
    +                <property name="receives_default">True</property>
    
    170
    +                <property name="tooltip_text" translatable="yes">Query Contact Info</property>
    
    171
    +                <property name="image">image4</property>
    
    172
    +                <signal name="clicked" handler="on_show_contact_info_button_clicked" swapped="no"/>
    
    119 173
                   </object>
    
    120 174
                   <packing>
    
    121 175
                     <property name="left_attach">2</property>
    
    122
    -                <property name="top_attach">2</property>
    
    176
    +                <property name="top_attach">0</property>
    
    123 177
                   </packing>
    
    124 178
                 </child>
    
    125 179
               </object>
    
    126 180
               <packing>
    
    127
    -            <property name="expand">False</property>
    
    181
    +            <property name="expand">True</property>
    
    128 182
                 <property name="fill">True</property>
    
    129 183
                 <property name="position">0</property>
    
    130 184
               </packing>
    
    131 185
             </child>
    
    132 186
             <child>
    
    133
    -          <object class="GtkScrolledWindow" id="conversation_scrolledwindow">
    
    187
    +          <object class="GtkGrid" id="received_grid">
    
    134 188
                 <property name="visible">True</property>
    
    135
    -            <property name="can_focus">True</property>
    
    189
    +            <property name="can_focus">False</property>
    
    136 190
                 <property name="no_show_all">True</property>
    
    137
    -            <property name="shadow_type">in</property>
    
    191
    +            <property name="row_spacing">6</property>
    
    192
    +            <property name="column_spacing">12</property>
    
    138 193
                 <child>
    
    139
    -              <placeholder/>
    
    194
    +              <object class="GtkLabel" id="from_label">
    
    195
    +                <property name="visible">True</property>
    
    196
    +                <property name="can_focus">False</property>
    
    197
    +                <property name="halign">end</property>
    
    198
    +                <property name="label" translatable="yes">_From</property>
    
    199
    +                <property name="use_underline">True</property>
    
    200
    +                <style>
    
    201
    +                  <class name="dim-label"/>
    
    202
    +                </style>
    
    203
    +              </object>
    
    204
    +              <packing>
    
    205
    +                <property name="left_attach">0</property>
    
    206
    +                <property name="top_attach">0</property>
    
    207
    +              </packing>
    
    208
    +            </child>
    
    209
    +            <child>
    
    210
    +              <object class="GtkLabel" id="subject_from_label">
    
    211
    +                <property name="visible">True</property>
    
    212
    +                <property name="can_focus">False</property>
    
    213
    +                <property name="halign">end</property>
    
    214
    +                <property name="label" translatable="yes">Subject</property>
    
    215
    +                <style>
    
    216
    +                  <class name="dim-label"/>
    
    217
    +                </style>
    
    218
    +              </object>
    
    219
    +              <packing>
    
    220
    +                <property name="left_attach">0</property>
    
    221
    +                <property name="top_attach">1</property>
    
    222
    +              </packing>
    
    223
    +            </child>
    
    224
    +            <child>
    
    225
    +              <object class="GtkLabel" id="from_entry_label">
    
    226
    +                <property name="visible">True</property>
    
    227
    +                <property name="can_focus">False</property>
    
    228
    +                <property name="label" translatable="yes">&lt;user@example.org&gt;</property>
    
    229
    +                <property name="xalign">0</property>
    
    230
    +                <style>
    
    231
    +                  <class name="bold"/>
    
    232
    +                </style>
    
    233
    +              </object>
    
    234
    +              <packing>
    
    235
    +                <property name="left_attach">1</property>
    
    236
    +                <property name="top_attach">0</property>
    
    237
    +              </packing>
    
    238
    +            </child>
    
    239
    +            <child>
    
    240
    +              <object class="GtkLabel" id="subject_from_entry_label">
    
    241
    +                <property name="visible">True</property>
    
    242
    +                <property name="can_focus">False</property>
    
    243
    +                <property name="label" translatable="yes">&lt;from Subject&gt;</property>
    
    244
    +                <property name="wrap">True</property>
    
    245
    +                <property name="max_width_chars">50</property>
    
    246
    +                <property name="xalign">0</property>
    
    247
    +              </object>
    
    248
    +              <packing>
    
    249
    +                <property name="left_attach">1</property>
    
    250
    +                <property name="top_attach">1</property>
    
    251
    +              </packing>
    
    140 252
                 </child>
    
    141
    -          </object>
    
    142
    -          <packing>
    
    143
    -            <property name="expand">True</property>
    
    144
    -            <property name="fill">True</property>
    
    145
    -            <property name="position">1</property>
    
    146
    -          </packing>
    
    147
    -        </child>
    
    148
    -        <child>
    
    149
    -          <object class="GtkScrolledWindow" id="message_scrolledwindow">
    
    150
    -            <property name="visible">True</property>
    
    151
    -            <property name="can_focus">True</property>
    
    152
    -            <property name="no_show_all">True</property>
    
    153
    -            <property name="shadow_type">in</property>
    
    154 253
                 <child>
    
    155
    -              <object class="GtkTextView" id="message_textview">
    
    254
    +              <object class="GtkScrolledWindow" id="conversation_scrolledwindow">
    
    255
    +                <property name="height_request">100</property>
    
    156 256
                     <property name="visible">True</property>
    
    157 257
                     <property name="can_focus">True</property>
    
    158
    -                <property name="wrap_mode">word</property>
    
    258
    +                <property name="hexpand">True</property>
    
    259
    +                <property name="vexpand">True</property>
    
    260
    +                <property name="shadow_type">in</property>
    
    261
    +                <child>
    
    262
    +                  <placeholder/>
    
    263
    +                </child>
    
    159 264
                   </object>
    
    265
    +              <packing>
    
    266
    +                <property name="left_attach">1</property>
    
    267
    +                <property name="top_attach">2</property>
    
    268
    +              </packing>
    
    269
    +            </child>
    
    270
    +            <child>
    
    271
    +              <object class="GtkLabel" id="message_label_received">
    
    272
    +                <property name="visible">True</property>
    
    273
    +                <property name="can_focus">False</property>
    
    274
    +                <property name="halign">end</property>
    
    275
    +                <property name="label" translatable="yes">Message</property>
    
    276
    +                <style>
    
    277
    +                  <class name="dim-label"/>
    
    278
    +                </style>
    
    279
    +              </object>
    
    280
    +              <packing>
    
    281
    +                <property name="left_attach">0</property>
    
    282
    +                <property name="top_attach">2</property>
    
    283
    +              </packing>
    
    160 284
                 </child>
    
    161 285
               </object>
    
    162 286
               <packing>
    
    163 287
                 <property name="expand">True</property>
    
    164 288
                 <property name="fill">True</property>
    
    165
    -            <property name="position">2</property>
    
    289
    +            <property name="position">1</property>
    
    166 290
               </packing>
    
    167 291
             </child>
    
    168 292
             <child>
    
    169
    -          <object class="GtkButtonBox" id="hbuttonbox26">
    
    293
    +          <object class="GtkButtonBox">
    
    170 294
                 <property name="visible">True</property>
    
    171 295
                 <property name="can_focus">False</property>
    
    296
    +            <property name="margin_top">12</property>
    
    172 297
                 <property name="spacing">12</property>
    
    173 298
                 <property name="layout_style">end</property>
    
    174 299
                 <child>
    
    ... ... @@ -188,23 +313,6 @@
    188 313
                     <property name="position">0</property>
    
    189 314
                   </packing>
    
    190 315
                 </child>
    
    191
    -            <child>
    
    192
    -              <object class="GtkButton" id="cancel_button">
    
    193
    -                <property name="label">gtk-cancel</property>
    
    194
    -                <property name="visible">True</property>
    
    195
    -                <property name="can_focus">True</property>
    
    196
    -                <property name="can_default">True</property>
    
    197
    -                <property name="receives_default">False</property>
    
    198
    -                <property name="no_show_all">True</property>
    
    199
    -                <property name="use_stock">True</property>
    
    200
    -                <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/>
    
    201
    -              </object>
    
    202
    -              <packing>
    
    203
    -                <property name="expand">False</property>
    
    204
    -                <property name="fill">False</property>
    
    205
    -                <property name="position">1</property>
    
    206
    -              </packing>
    
    207
    -            </child>
    
    208 316
                 <child>
    
    209 317
                   <object class="GtkButton" id="send_button">
    
    210 318
                     <property name="label" translatable="yes">Sen_d</property>
    
    ... ... @@ -214,7 +322,7 @@
    214 322
                     <property name="receives_default">False</property>
    
    215 323
                     <property name="no_show_all">True</property>
    
    216 324
                     <property name="tooltip_text" translatable="yes">Send message</property>
    
    217
    -                <property name="image">image3</property>
    
    325
    +                <property name="image">image2</property>
    
    218 326
                     <property name="use_underline">True</property>
    
    219 327
                     <signal name="clicked" handler="on_send_button_clicked" swapped="no"/>
    
    220 328
                   </object>
    
    ... ... @@ -236,6 +344,9 @@
    236 344
                     <property name="image">image1</property>
    
    237 345
                     <property name="use_underline">True</property>
    
    238 346
                     <signal name="clicked" handler="on_reply_button_clicked" swapped="no"/>
    
    347
    +                <style>
    
    348
    +                  <class name="suggested-action"/>
    
    349
    +                </style>
    
    239 350
                   </object>
    
    240 351
                   <packing>
    
    241 352
                     <property name="expand">False</property>
    
    ... ... @@ -252,9 +363,12 @@
    252 363
                     <property name="receives_default">False</property>
    
    253 364
                     <property name="no_show_all">True</property>
    
    254 365
                     <property name="tooltip_text" translatable="yes">Send message and close window</property>
    
    255
    -                <property name="image">image2</property>
    
    366
    +                <property name="image">image3</property>
    
    256 367
                     <property name="use_underline">True</property>
    
    257 368
                     <signal name="clicked" handler="on_send_and_close_button_clicked" swapped="no"/>
    
    369
    +                <style>
    
    370
    +                  <class name="suggested-action"/>
    
    371
    +                </style>
    
    258 372
                   </object>
    
    259 373
                   <packing>
    
    260 374
                     <property name="expand">False</property>
    
    ... ... @@ -267,7 +381,7 @@
    267 381
                 <property name="expand">False</property>
    
    268 382
                 <property name="fill">True</property>
    
    269 383
                 <property name="padding">6</property>
    
    270
    -            <property name="position">3</property>
    
    384
    +            <property name="position">4</property>
    
    271 385
               </packing>
    
    272 386
             </child>
    
    273 387
           </object>
    

  • gajim/gtk/single_message.py
    ... ... @@ -16,7 +16,9 @@ from typing import List # pylint: disable=unused-import
    16 16
     
    
    17 17
     from gi.repository import Gdk
    
    18 18
     from gi.repository import GLib
    
    19
    +from gi.repository import Gtk
    
    19 20
     
    
    21
    +from gajim import vcard
    
    20 22
     from gajim.common import app
    
    21 23
     from gajim.common import helpers
    
    22 24
     from gajim.common.i18n import _
    
    ... ... @@ -37,16 +39,17 @@ if app.is_installed('GSPELL'):
    37 39
         from gi.repository import Gspell  # pylint: disable=ungrouped-imports
    
    38 40
     
    
    39 41
     
    
    40
    -class SingleMessageWindow:
    
    42
    +class SingleMessageWindow(Gtk.ApplicationWindow):
    
    41 43
         """
    
    42 44
         SingleMessageWindow can send or show a received singled message depending on
    
    43 45
         action argument which can be 'send' or 'receive'
    
    44 46
         """
    
    45
    -    # Keep a reference on windows so garbage collector don't restroy them
    
    46
    -    instances = []  # type: List[SingleMessageWindow]
    
    47 47
         def __init__(self, account, to='', action='', from_whom='', subject='',
    
    48 48
                 message='', resource='', session=None, form_node=None):
    
    49
    -        self.instances.append(self)
    
    49
    +        Gtk.ApplicationWindow.__init__(self)
    
    50
    +        self.set_application(app.app)
    
    51
    +        self.set_title(_('Send Single Message'))
    
    52
    +        self.set_name('SendSingleMessageWindow')
    
    50 53
             self.account = account
    
    51 54
             self.action = action
    
    52 55
     
    
    ... ... @@ -57,51 +60,38 @@ class SingleMessageWindow:
    57 60
             self.resource = resource
    
    58 61
             self.session = session
    
    59 62
     
    
    60
    -        self.xml = get_builder('single_message_window.ui')
    
    61
    -        self.window = self.xml.get_object('single_message_window')
    
    62
    -        self.count_chars_label = self.xml.get_object('count_chars_label')
    
    63
    -        self.from_label = self.xml.get_object('from_label')
    
    64
    -        self.from_entry = self.xml.get_object('from_entry')
    
    65
    -        self.to_label = self.xml.get_object('to_label')
    
    66
    -        self.to_entry = self.xml.get_object('to_entry')
    
    67
    -        self.subject_entry = self.xml.get_object('subject_entry')
    
    68
    -        self.message_scrolledwindow = self.xml.get_object(
    
    69
    -                'message_scrolledwindow')
    
    70
    -        self.message_textview = self.xml.get_object('message_textview')
    
    71
    -        self.message_tv_buffer = self.message_textview.get_buffer()
    
    72
    -        self.conversation_scrolledwindow = self.xml.get_object(
    
    73
    -                'conversation_scrolledwindow')
    
    63
    +        self._ui = get_builder('single_message_window.ui')
    
    64
    +        self.message_tv_buffer = self._ui.message_textview.get_buffer()
    
    74 65
             self.conversation_textview = ConversationTextview(
    
    75 66
                 account, used_in_history_window=True)
    
    76 67
             self.conversation_textview.tv.show()
    
    68
    +        self.conversation_textview.tv.set_left_margin(6)
    
    69
    +        self.conversation_textview.tv.set_right_margin(6)
    
    70
    +        self.conversation_textview.tv.set_top_margin(6)
    
    71
    +        self.conversation_textview.tv.set_bottom_margin(6)
    
    77 72
             self.conversation_tv_buffer = self.conversation_textview.tv.get_buffer()
    
    78
    -        self.xml.get_object('conversation_scrolledwindow').add(
    
    79
    -                self.conversation_textview.tv)
    
    73
    +        self._ui.conversation_scrolledwindow.add(
    
    74
    +            self.conversation_textview.tv)
    
    80 75
     
    
    81 76
             self.form_widget = None
    
    82
    -        parent_box = self.xml.get_object('conversation_scrolledwindow').\
    
    83
    -                           get_parent()
    
    77
    +        parent_box = self._ui.conversation_scrolledwindow.get_parent()
    
    84 78
             if form_node:
    
    85 79
                 self.form_widget = DataFormWidget(form_node)
    
    86 80
                 self.form_widget.show_all()
    
    81
    +            self._ui.conversation_scrolledwindow.hide()
    
    82
    +            self._ui.message_label_received.hide()
    
    87 83
                 parent_box.add(self.form_widget)
    
    88
    -            parent_box.child_set_property(self.form_widget, 'position',
    
    89
    -                parent_box.child_get_property(self.xml.get_object(
    
    90
    -                'conversation_scrolledwindow'), 'position'))
    
    84
    +            parent_box.child_set_property(self.form_widget, 'top-attach', 2)
    
    85
    +            parent_box.child_set_property(self.form_widget, 'left-attach', 0)
    
    86
    +            parent_box.child_set_property(self.form_widget, 'width', 2)
    
    91 87
                 self.action = 'form'
    
    92 88
     
    
    93
    -        self.send_button = self.xml.get_object('send_button')
    
    94
    -        self.reply_button = self.xml.get_object('reply_button')
    
    95
    -        self.send_and_close_button = self.xml.get_object('send_and_close_button')
    
    96
    -        self.cancel_button = self.xml.get_object('cancel_button')
    
    97
    -        self.close_button = self.xml.get_object('close_button')
    
    98 89
             self.message_tv_buffer.connect('changed', self.update_char_counter)
    
    99 90
             if isinstance(to, list):
    
    100 91
                 jid = ', '.join([i[0].get_full_jid() for i in to])
    
    101
    -            self.to_entry.set_text(jid)
    
    102
    -            self.to_entry.set_sensitive(False)
    
    92
    +            self._ui.to_entry.set_text(jid)
    
    103 93
             else:
    
    104
    -            self.to_entry.set_text(to)
    
    94
    +            self._ui.to_entry.set_text(to)
    
    105 95
     
    
    106 96
             if app.config.get('use_speller') and app.is_installed('GSPELL') and action == 'send':
    
    107 97
                 lang = app.config.get('speller_language')
    
    ... ... @@ -110,10 +100,10 @@ class SingleMessageWindow:
    110 100
                     AspellDictError(lang)
    
    111 101
                 else:
    
    112 102
                     spell_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(
    
    113
    -                    self.message_textview.get_buffer())
    
    103
    +                    self._ui.message_textview.get_buffer())
    
    114 104
                     spell_buffer.set_spell_checker(Gspell.Checker.new(gspell_lang))
    
    115 105
                     spell_view = Gspell.TextView.get_from_gtk_text_view(
    
    116
    -                    self.message_textview)
    
    106
    +                    self._ui.message_textview)
    
    117 107
                     spell_view.set_inline_spell_checking(True)
    
    118 108
                     spell_view.set_enable_language_menu(True)
    
    119 109
     
    
    ... ... @@ -121,12 +111,12 @@ class SingleMessageWindow:
    121 111
     
    
    122 112
             # set_text(None) raises TypeError exception
    
    123 113
             if self.subject is None:
    
    124
    -            self.subject = ''
    
    125
    -        self.subject_entry.set_text(self.subject)
    
    126
    -
    
    114
    +            self.subject = _('(No subject)')
    
    115
    +        self._ui.subject_entry.set_text(self.subject)
    
    116
    +        self._ui.subject_from_entry_label.set_text(self.subject)
    
    127 117
     
    
    128 118
             if to == '':
    
    129
    -            liststore = get_completion_liststore(self.to_entry)
    
    119
    +            liststore = get_completion_liststore(self._ui.to_entry)
    
    130 120
                 self.completion_dict = helpers.get_contact_dict_for_account(account)
    
    131 121
                 keys = sorted(self.completion_dict.keys())
    
    132 122
                 for jid in keys:
    
    ... ... @@ -135,20 +125,21 @@ class SingleMessageWindow:
    135 125
                     liststore.append((status_icon, jid))
    
    136 126
             else:
    
    137 127
                 self.completion_dict = {}
    
    138
    -        self.xml.connect_signals(self)
    
    128
    +
    
    129
    +        self._ui.to_entry.connect('changed', self.on_to_entry_changed)
    
    130
    +        self._ui.connect_signals(self)
    
    139 131
     
    
    140 132
             # get window position and size from config
    
    141
    -        resize_window(self.window,
    
    133
    +        resize_window(self._ui.single_message_window,
    
    142 134
                 app.config.get('single-msg-width'),
    
    143 135
                 app.config.get('single-msg-height'))
    
    144
    -        move_window(self.window,
    
    136
    +        move_window(self._ui.single_message_window,
    
    145 137
                 app.config.get('single-msg-x-position'),
    
    146 138
                 app.config.get('single-msg-y-position'))
    
    147 139
     
    
    148
    -        self.window.show_all()
    
    140
    +        self._ui.single_message_window.show_all()
    
    149 141
     
    
    150 142
         def on_single_message_window_destroy(self, widget):
    
    151
    -        self.instances.remove(self)
    
    152 143
             c = app.contacts.get_contact_with_highest_priority(self.account,
    
    153 144
                     self.from_whom)
    
    154 145
             if not c:
    
    ... ... @@ -166,16 +157,44 @@ class SingleMessageWindow:
    166 157
     
    
    167 158
         def save_pos(self):
    
    168 159
             # save the window size and position
    
    169
    -        x, y = self.window.get_position()
    
    160
    +        x, y = self._ui.single_message_window.get_position()
    
    170 161
             app.config.set('single-msg-x-position', x)
    
    171 162
             app.config.set('single-msg-y-position', y)
    
    172
    -        width, height = self.window.get_size()
    
    163
    +        width, height = self._ui.single_message_window.get_size()
    
    173 164
             app.config.set('single-msg-width', width)
    
    174 165
             app.config.set('single-msg-height', height)
    
    175 166
     
    
    176 167
         def on_single_message_window_delete_event(self, window, ev):
    
    177 168
             self.save_pos()
    
    178 169
     
    
    170
    +    def on_show_contact_info_button_clicked(self, widget):
    
    171
    +        """
    
    172
    +        Ask for vCard
    
    173
    +        """
    
    174
    +        entry = self._ui.to_entry.get_text().strip()
    
    175
    +
    
    176
    +        keys = sorted(self.completion_dict.keys())
    
    177
    +        for key in keys:
    
    178
    +            contact = self.completion_dict[key]
    
    179
    +            if entry in key:
    
    180
    +                entry = contact.jid
    
    181
    +                break
    
    182
    +
    
    183
    +        if entry in app.interface.instances[self.account]['infos']:
    
    184
    +            app.interface.instances[self.account]['infos'][entry].window.present()
    
    185
    +        else:
    
    186
    +            contact = app.contacts.create_contact(jid=entry, account=self.account)
    
    187
    +            app.interface.instances[self.account]['infos'][entry] = \
    
    188
    +                     vcard.VcardWindow(contact, self.account)
    
    189
    +            # Remove xmpp page
    
    190
    +            app.interface.instances[self.account]['infos'][entry].xml.\
    
    191
    +                     get_object('information_notebook').remove_page(0)
    
    192
    +
    
    193
    +    def on_to_entry_changed(self, widget):
    
    194
    +        entry = self._ui.to_entry.get_text()
    
    195
    +        is_empty = bool(not entry == '' and not ',' in entry)
    
    196
    +        self._ui.show_contact_info_button.set_sensitive(is_empty)
    
    197
    +
    
    179 198
         def prepare_widgets_for(self, action):
    
    180 199
             if len(app.connections) > 1:
    
    181 200
                 if action == 'send':
    
    ... ... @@ -187,75 +206,67 @@ class SingleMessageWindow:
    187 206
     
    
    188 207
             if action == 'send': # prepare UI for Sending
    
    189 208
                 title = _('Send %s') % title
    
    190
    -            self.send_button.show()
    
    191
    -            self.send_and_close_button.show()
    
    192
    -            self.to_label.show()
    
    193
    -            self.to_entry.show()
    
    194
    -            self.reply_button.hide()
    
    195
    -            self.from_label.hide()
    
    196
    -            self.from_entry.hide()
    
    197
    -            self.conversation_scrolledwindow.hide()
    
    198
    -            self.message_scrolledwindow.show()
    
    209
    +            self._ui.send_button.show()
    
    210
    +            self._ui.send_and_close_button.show()
    
    211
    +            self._ui.reply_button.hide()
    
    212
    +            self._ui.close_button.hide()
    
    213
    +
    
    214
    +            self._ui.send_grid.show()
    
    215
    +            self._ui.received_grid.hide()
    
    199 216
     
    
    200 217
                 if self.message: # we come from a reply?
    
    201
    -                self.message_textview.grab_focus()
    
    202
    -                self.cancel_button.hide()
    
    203
    -                self.close_button.show()
    
    218
    +                self._ui.show_contact_info_button.set_sensitive(True)
    
    219
    +                self._ui.message_textview.grab_focus()
    
    204 220
                     self.message_tv_buffer.set_text(self.message)
    
    205 221
                     GLib.idle_add(self.set_cursor_to_end)
    
    206 222
                 else: # we write a new message (not from reply)
    
    207
    -                self.close_button.hide()
    
    208 223
                     if self.to: # do we already have jid?
    
    209
    -                    self.subject_entry.grab_focus()
    
    224
    +                    self._ui.subject_entry.grab_focus()
    
    210 225
     
    
    211 226
             elif action == 'receive': # prepare UI for Receiving
    
    212 227
                 title = _('Received %s') % title
    
    213
    -            self.reply_button.show()
    
    214
    -            self.from_label.show()
    
    215
    -            self.from_entry.show()
    
    216
    -            self.send_button.hide()
    
    217
    -            self.send_and_close_button.hide()
    
    218
    -            self.to_label.hide()
    
    219
    -            self.to_entry.hide()
    
    220
    -            self.conversation_scrolledwindow.show()
    
    221
    -            self.message_scrolledwindow.hide()
    
    228
    +            self._ui.reply_button.show()
    
    229
    +            self._ui.close_button.show()
    
    230
    +            self._ui.send_button.hide()
    
    231
    +            self._ui.send_and_close_button.hide()
    
    232
    +            self._ui.reply_button.grab_focus()
    
    233
    +
    
    234
    +            self._ui.received_grid.show()
    
    235
    +            self._ui.send_grid.hide()
    
    222 236
     
    
    223 237
                 if self.message:
    
    224 238
                     self.conversation_textview.print_real_text(self.message)
    
    225 239
                 fjid = self.from_whom
    
    226 240
                 if self.resource:
    
    227 241
                     fjid += '/' + self.resource # Full jid of sender (with resource)
    
    228
    -            self.from_entry.set_text(fjid)
    
    229
    -            self.from_entry.set_property('editable', False)
    
    230
    -            self.subject_entry.set_property('editable', False)
    
    231
    -            self.reply_button.grab_focus()
    
    232
    -            self.cancel_button.hide()
    
    233
    -            self.close_button.show()
    
    242
    +            self._ui.from_entry_label.set_text(fjid)
    
    243
    +
    
    234 244
             elif action == 'form': # prepare UI for Receiving
    
    235
    -            title = _('Form %s') % title
    
    236
    -            self.send_button.show()
    
    237
    -            self.send_and_close_button.show()
    
    238
    -            self.to_label.show()
    
    239
    -            self.to_entry.show()
    
    240
    -            self.reply_button.hide()
    
    241
    -            self.from_label.hide()
    
    242
    -            self.from_entry.hide()
    
    243
    -            self.conversation_scrolledwindow.hide()
    
    244
    -            self.message_scrolledwindow.hide()
    
    245
    -
    
    246
    -        self.window.set_title(title)
    
    247
    -
    
    248
    -    def on_cancel_button_clicked(self, widget):
    
    249
    -        self.save_pos()
    
    250
    -        self.window.destroy()
    
    245
    +            title = self.form_widget.title
    
    246
    +            title = _('Form: %s') % title
    
    247
    +            self._ui.send_button.hide()
    
    248
    +            self._ui.send_and_close_button.hide()
    
    249
    +            self._ui.reply_button.show()
    
    250
    +            self._ui.close_button.show()
    
    251
    +
    
    252
    +            self._ui.send_grid.hide()
    
    253
    +            self._ui.received_grid.show()
    
    254
    +
    
    255
    +            fjid = self.from_whom
    
    256
    +            if self.resource:
    
    257
    +                fjid += '/' + self.resource # Full jid of sender (with resource)
    
    258
    +            self._ui.from_entry_label.set_text(fjid)
    
    259
    +
    
    260
    +        self._ui.single_message_window.set_title(title)
    
    251 261
     
    
    252 262
         def on_close_button_clicked(self, widget):
    
    253 263
             self.save_pos()
    
    254
    -        self.window.destroy()
    
    264
    +        self._ui.single_message_window.destroy()
    
    255 265
     
    
    256 266
         def update_char_counter(self, widget):
    
    257 267
             characters_no = self.message_tv_buffer.get_char_count()
    
    258
    -        self.count_chars_label.set_text(str(characters_no))
    
    268
    +        self._ui.count_chars_label.set_text(
    
    269
    +            _('Characters typed: %s') % str(characters_no))
    
    259 270
     
    
    260 271
         def send_single_message(self):
    
    261 272
             if app.connections[self.account].connected <= 1:
    
    ... ... @@ -271,10 +282,10 @@ class SingleMessageWindow:
    271 282
                     else:
    
    272 283
                         sender_list.append(i[0].jid)
    
    273 284
             else:
    
    274
    -            sender_list = [j.strip() for j in self.to_entry.get_text().split(
    
    285
    +            sender_list = [j.strip() for j in self._ui.to_entry.get_text().split(
    
    275 286
                     ',')]
    
    276 287
     
    
    277
    -        subject = self.subject_entry.get_text()
    
    288
    +        subject = self._ui.subject_entry.get_text()
    
    278 289
             begin, end = self.message_tv_buffer.get_bounds()
    
    279 290
             message = self.message_tv_buffer.get_text(begin, end, True)
    
    280 291
     
    
    ... ... @@ -292,8 +303,8 @@ class SingleMessageWindow:
    292 303
                     to_whom_jid = helpers.parse_jid(to_whom_jid)
    
    293 304
                 except helpers.InvalidFormat:
    
    294 305
                     ErrorDialog(_('Invalid JID'),
    
    295
    -                    _('It is not possible to send a message to %s, this JID is not '
    
    296
    -                    'valid.') % to_whom_jid)
    
    306
    +                    _('It is not possible to send a message to %s, this JID '
    
    307
    +                      'is not valid.') % to_whom_jid)
    
    297 308
                     return True
    
    298 309
     
    
    299 310
                 if '/announce/' in to_whom_jid:
    
    ... ... @@ -307,7 +318,7 @@ class SingleMessageWindow:
    307 318
                 account=self.account, jid=recipient_list, message=message,
    
    308 319
                 type_='normal', subject=subject, form_node=form_node))
    
    309 320
     
    
    310
    -        self.subject_entry.set_text('') # we sent ok, clear the subject
    
    321
    +        self._ui.subject_entry.set_text('') # we sent ok, clear the subject
    
    311 322
             self.message_tv_buffer.set_text('') # we sent ok, clear the textview
    
    312 323
     
    
    313 324
         def on_send_button_clicked(self, widget):
    
    ... ... @@ -319,7 +330,7 @@ class SingleMessageWindow:
    319 330
             self.message = _('%s wrote:\n') % self.from_whom + self.message
    
    320 331
             # add > at the begining of each line
    
    321 332
             self.message = self.message.replace('\n', '\n> ') + '\n\n'
    
    322
    -        self.window.destroy()
    
    333
    +        self._ui.single_message_window.destroy()
    
    323 334
             SingleMessageWindow(self.account, to=self.from_whom, action='send',
    
    324 335
                 from_whom=self.from_whom, subject=self.subject, message=self.message,
    
    325 336
                 session=self.session)
    
    ... ... @@ -328,9 +339,9 @@ class SingleMessageWindow:
    328 339
             if self.send_single_message():
    
    329 340
                 return
    
    330 341
             self.save_pos()
    
    331
    -        self.window.destroy()
    
    342
    +        self._ui.single_message_window.destroy()
    
    332 343
     
    
    333 344
         def on_single_message_window_key_press_event(self, widget, event):
    
    334 345
             if event.keyval == Gdk.KEY_Escape: # ESCAPE
    
    335 346
                 self.save_pos()
    
    336
    -            self.window.destroy()
    347
    +            self._ui.single_message_window.destroy()