Commit e79e98c428e6d8241050318f4d3a986eaf250dcd

Authored by Perry Werneck
2 parents 0f3ebf1c b71485a6
Exists in master and in 1 other branch develop

Merge branch 'develop'

locale/pt_BR.po
... ... @@ -5,8 +5,8 @@ msgid ""
5 5 msgstr ""
6 6 "Project-Id-Version: pw3270 5.0\n"
7 7 "Report-Msgid-Bugs-To: \n"
8   -"POT-Creation-Date: 2020-07-03 12:42-0300\n"
9   -"PO-Revision-Date: 2020-07-03 15:04-0300\n"
  8 +"POT-Creation-Date: 2020-08-03 15:22-0300\n"
  9 +"PO-Revision-Date: 2020-08-03 15:26-0300\n"
10 10 "Last-Translator: Perry Werneck <perry.werneck@gmail.com>\n"
11 11 "Language-Team: Português <>\n"
12 12 "Language: pt_BR\n"
... ... @@ -59,15 +59,15 @@ msgstr &quot;_Adicionar ao arquivo&quot;
59 59 msgid "About security"
60 60 msgstr "Sobre a segurança"
61 61  
62   -#: src/dialogs/settings/accelerator.c:191
  62 +#: src/dialogs/settings/accelerator.c:196
63 63 msgid "Accelerator"
64 64 msgstr "Atalho"
65 65  
66   -#: src/dialogs/settings/accelerator.c:329
  66 +#: src/dialogs/settings/accelerator.c:334
67 67 msgid "Accelerator is in use"
68 68 msgstr "Atalho está em uso"
69 69  
70   -#: src/dialogs/settings/accelerator.c:240
  70 +#: src/dialogs/settings/accelerator.c:245
71 71 msgid "Accelerators"
72 72 msgstr "Atalhos"
73 73  
... ... @@ -88,7 +88,7 @@ msgstr &quot;Adicionar à cópia&quot;
88 88 msgid "Address or name of the host to connect."
89 89 msgstr "Endereço ou nome do host a conectar."
90 90  
91   -#: src/dialogs/settings/accelerator.c:201
  91 +#: src/dialogs/settings/accelerator.c:206
92 92 msgid "Alternative"
93 93 msgstr "Alternativa"
94 94  
... ... @@ -120,7 +120,7 @@ msgstr &quot;Adiciona seleção na área de transferência&quot;
120 120 msgid "Appends the source file to the destination file."
121 121 msgstr "Adiciona conteúdo do arquivo origem ao final do arquivo destino."
122 122  
123   -#: src/dialogs/settings/accelerator.c:311
  123 +#: src/dialogs/settings/accelerator.c:316
124 124 #, c-format
125 125 msgid "Assign it to action (<b>%s</b>)?"
126 126 msgstr "Associar com a ação (<b>%s</b>)?"
... ... @@ -162,7 +162,7 @@ msgstr &quot;Azul&quot;
162 162 msgid "Bold"
163 163 msgstr "Negrito"
164 164  
165   -#: src/dialogs/load.c:181 src/dialogs/save/save.c:216
  165 +#: src/dialogs/load.c:181 src/dialogs/save/save.c:268
166 166 msgid "C_haracter Coding"
167 167 msgstr "C_odificação de caracteres"
168 168  
... ... @@ -202,7 +202,7 @@ msgstr &quot;Erro ao converter valor do cgcsid&quot;
202 202 msgid "Can't parse character value"
203 203 msgstr "Erro ao analisar valor de caractere"
204 204  
205   -#: src/selection/windows/paste.c:79 src/selection/windows/paste.c:119
  205 +#: src/selection/linux/paste.c:81 src/selection/linux/paste.c:115
206 206 msgid "Can't paste"
207 207 msgstr "Não é possivel colar"
208 208  
... ... @@ -211,7 +211,7 @@ msgid &quot;Can&#39;t paste text&quot;
211 211 msgstr "Não é possível colar texto"
212 212  
213 213 #: src/filetransfer/save.c:117 src/filetransfer/activitylist.c:436
214   -#: src/trace/trace.c:486 src/dialogs/transfer.c:91 src/dialogs/save/save.c:461
  214 +#: src/trace/trace.c:486 src/dialogs/transfer.c:91 src/dialogs/save/save.c:627
215 215 #, c-format
216 216 msgid "Can't save %s"
217 217 msgstr "Não foi possível salvar arquivo %s"
... ... @@ -220,7 +220,7 @@ msgstr &quot;Não foi possível salvar arquivo %s&quot;
220 220 msgid "Can't set callback table"
221 221 msgstr "Não foi possível setar a tabela de retornos"
222 222  
223   -#: src/terminal/iocallback.c:199
  223 +#: src/terminal/iocallback.c:200
224 224 msgid "Can't set lib3270 I/O controller"
225 225 msgstr "Não foi possível registrar manipuladores de I/O 3270"
226 226  
... ... @@ -228,25 +228,21 @@ msgstr &quot;Não foi possível registrar manipuladores de I/O 3270&quot;
228 228 msgid "Can't start file transfer session"
229 229 msgstr "Não foi possível iniciar transferência de arquivo"
230 230  
231   -#: src/terminal/callbacks.c:396 src/filetransfer/v3270ftprogress.c:433
232   -#: src/filetransfer/transfer.c:89 src/dialogs/load.c:111
233   -#: src/dialogs/save/save.c:136 src/dialogs/settings/host.c:401
  231 +#: src/filetransfer/v3270ftprogress.c:433 src/filetransfer/transfer.c:89
  232 +#: src/dialogs/load.c:111 src/dialogs/save/save.c:117
  233 +#: src/dialogs/settings/host.c:401
234 234 msgid "Cancel"
235   -msgstr "_Cancelar"
  235 +msgstr "Cancelar"
236 236  
237 237 #: src/filetransfer/transfer.c:90
238 238 msgid "Cancel transfer operation."
239 239 msgstr "Cancelar transferência"
240 240  
241   -#: src/dialogs/settings/host.c:546
242   -msgid "Check for SSL secure connection."
243   -msgstr "Marcar para ativar a conexão segura via SSL."
244   -
245 241 #: src/filetransfer/tables.c:44
246 242 msgid "Check this if the file consists of character data only."
247 243 msgstr "Marque se o arquivo contem apenas texto."
248 244  
249   -#: src/dialogs/load.c:206 src/dialogs/save/save.c:268
  245 +#: src/dialogs/load.c:206 src/dialogs/save/save.c:343
250 246 msgid "Click to cancel operation"
251 247 msgstr "Clique para cancelar operação"
252 248  
... ... @@ -254,11 +250,11 @@ msgstr &quot;Clique para cancelar operação&quot;
254 250 msgid "Click to load file"
255 251 msgstr "Clique para carregar arquivo"
256 252  
257   -#: src/dialogs/save/save.c:273
  253 +#: src/dialogs/save/save.c:348
258 254 msgid "Click to save file"
259 255 msgstr "Clique para salvar arquivo"
260 256  
261   -#: src/dialogs/settings/clipboard.c:409
  257 +#: src/dialogs/settings/clipboard.c:420
262 258 msgid "Clipboard"
263 259 msgstr "Área de transferência"
264 260  
... ... @@ -266,7 +262,7 @@ msgstr &quot;Área de transferência&quot;
266 262 msgid "Clipboard name"
267 263 msgstr "Nome da área de transferência"
268 264  
269   -#: src/dialogs/settings/clipboard.c:408
  265 +#: src/dialogs/settings/clipboard.c:419
270 266 msgid "Clipboard properties"
271 267 msgstr "Configuração da área de transferência"
272 268  
... ... @@ -302,10 +298,6 @@ msgstr &quot;Comando a executar&quot;
302 298 msgid "Connection"
303 299 msgstr "Conexão"
304 300  
305   -#: src/terminal/callbacks.c:397
306   -msgid "Continue"
307   -msgstr "Continuar"
308   -
309 301 #: src/terminal/actions/table.c:64 src/terminal/actions/table.c:87
310 302 msgid "Copy"
311 303 msgstr "Copiar"
... ... @@ -318,7 +310,7 @@ msgstr &quot;Copiar como texto puro&quot;
318 310 msgid "Copy as table"
319 311 msgstr "Copiar como tabela"
320 312  
321   -#: src/dialogs/settings/clipboard.c:239
  313 +#: src/dialogs/settings/clipboard.c:250
322 314 msgid "Copy options"
323 315 msgstr "Opções da cópia"
324 316  
... ... @@ -405,7 +397,7 @@ msgstr &quot;Turquesa Escuro&quot;
405 397 msgid "Default"
406 398 msgstr "Padrão"
407 399  
408   -#: src/dialogs/popups.c:149
  400 +#: src/dialogs/popups.c:132
409 401 msgid "Don't ask again"
410 402 msgstr "Não perguntar de novo"
411 403  
... ... @@ -425,14 +417,14 @@ msgstr &quot;Emulação&quot;
425 417 msgid "Enabled"
426 418 msgstr "Habilitado"
427 419  
428   -#: src/dialogs/popups.c:56 src/dialogs/popups.c:85
429   -msgid "Error"
430   -msgstr "Erro"
431   -
432 420 #: src/dialogs/print/print.c:72
433 421 msgid "Error on print operation"
434 422 msgstr "Erro na operação de impressão"
435 423  
  424 +#: src/dialogs/save/save.c:579
  425 +msgid "Error saving image"
  426 +msgstr "Erro ao salvar imagem"
  427 +
436 428 #: src/filetransfer/tables.c:224
437 429 msgid "Estimated transfer arrival"
438 430 msgstr "Tempo estimado para a transferência"
... ... @@ -441,7 +433,7 @@ msgstr &quot;Tempo estimado para a transferência&quot;
441 433 msgid "Field colors"
442 434 msgstr "Cor dos campos"
443 435  
444   -#: src/dialogs/save/save.c:230
  436 +#: src/dialogs/save/save.c:282
445 437 msgid "File _Format"
446 438 msgstr "_Formato do arquivo"
447 439  
... ... @@ -524,15 +516,15 @@ msgstr &quot;Cinza&quot;
524 516 msgid "Green"
525 517 msgstr "Verde"
526 518  
527   -#: src/dialogs/settings/clipboard.c:241
  519 +#: src/dialogs/settings/clipboard.c:252
528 520 msgid "HTML options"
529 521 msgstr "Opções HTML"
530 522  
531   -#: src/dialogs/settings/host.c:635
  523 +#: src/dialogs/settings/host.c:664
532 524 msgid "Host"
533 525 msgstr "Servidor"
534 526  
535   -#: src/dialogs/settings/host.c:634
  527 +#: src/dialogs/settings/host.c:663
536 528 msgid "Host settings"
537 529 msgstr "Configurações do servidor"
538 530  
... ... @@ -568,6 +560,10 @@ msgstr &quot;Ignore&quot;
568 560 msgid "Ignore the fail and remove the file from queue."
569 561 msgstr "Ignore the fail and remove the file from queue."
570 562  
  563 +#: src/dialogs/settings/clipboard.c:173
  564 +msgid "Image copy"
  565 +msgstr "Copiar imagem"
  566 +
571 567 #: src/terminal/actions/table.c:196
572 568 msgid "Increase the font size"
573 569 msgstr "Aumenta o tamanho da fonte"
... ... @@ -588,10 +584,14 @@ msgstr &quot;Intensificado/Protegido&quot;
588 584 msgid "Intensified/Unprotected"
589 585 msgstr "Intensificado/Desprotegido"
590 586  
591   -#: src/terminal/callbacks.c:424
592   -msgid "Invalid callback table, possible version mismatch in lib3270"
  587 +#: src/terminal/callbacks.c:463
  588 +#, c-format
  589 +msgid ""
  590 +"Invalid callback table, the release %s of lib%s can't be used (expecting "
  591 +"revision %s)"
593 592 msgstr ""
594   -"Tabela de callbacks inválida, possível divergência de versão na lib3270"
  593 +"Tabela de callbacks inválida, a revisão %s da lib%s não pode ser usada "
  594 +"(esperando a revisão %s)"
595 595  
596 596 #: src/terminal/charset.c:132
597 597 msgid "Invalid cgcsgid value"
... ... @@ -605,8 +605,8 @@ msgstr &quot;Escopo de mapeamento inválido&quot;
605 605 msgid "Invalid state"
606 606 msgstr "Estado inválido"
607 607  
608   -#: src/dialogs/settings/accelerator.c:145
609   -#: src/dialogs/settings/accelerator.c:239
  608 +#: src/dialogs/settings/accelerator.c:150
  609 +#: src/dialogs/settings/accelerator.c:244
610 610 msgid "Keyboard accelerators"
611 611 msgstr "Atalhos de teclado"
612 612  
... ... @@ -662,7 +662,7 @@ msgstr &quot;Monocromático&quot;
662 662 msgid "Mustard"
663 663 msgstr "Mostarda"
664 664  
665   -#: src/dialogs/settings/accelerator.c:153
  665 +#: src/dialogs/settings/accelerator.c:158
666 666 msgid "Name"
667 667 msgstr "Nome"
668 668  
... ... @@ -678,7 +678,7 @@ msgstr &quot;Próxima página&quot;
678 678 msgid "No active transfer"
679 679 msgstr "Nenhuma transferência ativa"
680 680  
681   -#: src/terminal/properties/get.c:198
  681 +#: src/terminal/properties/get.c:205
682 682 msgid "No host defined"
683 683 msgstr "Nenhum servidor definido"
684 684  
... ... @@ -694,14 +694,18 @@ msgstr &quot;Nenhuma transferência&quot;
694 694 msgid "No transfer in progress"
695 695 msgstr "Nenhuma transferência em andamento"
696 696  
697   -#: src/dialogs/settings/clipboard.c:306
  697 +#: src/dialogs/settings/clipboard.c:317
698 698 msgid "None (Don't export color)"
699 699 msgstr "Nenhum (Não exporta cores)"
700 700  
701   -#: src/dialogs/settings/clipboard.c:426
  701 +#: src/dialogs/settings/clipboard.c:437
702 702 msgid "None (Don't export font name)"
703 703 msgstr "Nenhuma (Não exporta fontes)"
704 704  
  705 +#: src/selection/linux/paste.c:117
  706 +msgid "None of the screens in the clipboard match with the current one."
  707 +msgstr "Nenhuma das telas da área de transferência corresponde à atual."
  708 +
705 709 #: src/dialogs/settings/colors.c:174
706 710 msgid "Normal/Protected"
707 711 msgstr "Normal/Protegido"
... ... @@ -710,7 +714,7 @@ msgstr &quot;Normal/Protegido&quot;
710 714 msgid "Normal/Unprotected"
711 715 msgstr "Normal/Desprotegido"
712 716  
713   -#: src/selection/windows/paste.c:75
  717 +#: src/selection/linux/paste.c:77
714 718 msgid "Not the same terminal type"
715 719 msgstr "O tipo de terminal é diferente"
716 720  
... ... @@ -742,10 +746,6 @@ msgstr &quot;Estado normal na OIA&quot;
742 746 msgid "Open"
743 747 msgstr "Abrir"
744 748  
745   -#: src/dialogs/popups.c:116
746   -msgid "Operation failed"
747   -msgstr "Operação falhou"
748   -
749 749 #: src/dialogs/save/convenience.c:65 src/dialogs/save/convenience.c:93
750 750 msgid "Operation has failed"
751 751 msgstr "Operação falhou"
... ... @@ -802,7 +802,7 @@ msgstr &quot;Colar de um arquivo&quot;
802 802 msgid "Paste from text file"
803 803 msgstr "Colar de um arquivo texto"
804 804  
805   -#: src/dialogs/settings/clipboard.c:240
  805 +#: src/dialogs/settings/clipboard.c:251
806 806 msgid "Paste options"
807 807 msgstr "Opções para colar"
808 808  
... ... @@ -830,7 +830,7 @@ msgstr &quot;Rosa&quot;
830 830 msgid "Plain text"
831 831 msgstr "Texto puro"
832 832  
833   -#: src/dialogs/settings/clipboard.c:374
  833 +#: src/dialogs/settings/clipboard.c:385
834 834 msgid "Plain text only"
835 835 msgstr "Apenas texto puro"
836 836  
... ... @@ -938,7 +938,7 @@ msgstr &quot;Formato de registro&quot;
938 938 msgid "Red"
939 939 msgstr "Vermelho"
940 940  
941   -#: src/dialogs/settings/accelerator.c:454
  941 +#: src/dialogs/settings/accelerator.c:459
942 942 msgid "Rejected by action"
943 943 msgstr "Rejeitado pela ação"
944 944  
... ... @@ -987,7 +987,11 @@ msgstr &quot;&quot;
987 987 "SPACE can be specified in units of TRACKS, CYLINDERS, or AVBLOCK, and only "
988 988 "one option can be used."
989 989  
990   -#: src/dialogs/settings/clipboard.c:307 src/dialogs/settings/clipboard.c:427
  990 +#: src/dialogs/settings/host.c:560
  991 +msgid "SSL/TLS"
  992 +msgstr "SSL/TLS"
  993 +
  994 +#: src/dialogs/settings/clipboard.c:318 src/dialogs/settings/clipboard.c:438
991 995 msgid "Same of the screen"
992 996 msgstr "Igual ao terminal"
993 997  
... ... @@ -1009,7 +1013,7 @@ msgstr &quot;Salvar _Como&quot;
1009 1013 msgid "Save all"
1010 1014 msgstr "Salvar tela"
1011 1015  
1012   -#: src/terminal/actions/table.c:262 src/dialogs/save/save.c:302
  1016 +#: src/terminal/actions/table.c:262 src/dialogs/save/save.c:377
1013 1017 msgid "Save copy"
1014 1018 msgstr "Salvar cópia"
1015 1019  
... ... @@ -1029,11 +1033,11 @@ msgstr &quot;Salvar tela ou seleção&quot;
1029 1033 msgid "Save selected"
1030 1034 msgstr "Salvar seleção"
1031 1035  
1032   -#: src/terminal/actions/table.c:253 src/dialogs/save/save.c:301
  1036 +#: src/terminal/actions/table.c:253 src/dialogs/save/save.c:376
1033 1037 msgid "Save selected area"
1034 1038 msgstr "Salvar área selecionada"
1035 1039  
1036   -#: src/dialogs/save/save.c:300
  1040 +#: src/dialogs/save/save.c:375
1037 1041 msgid "Save terminal contents"
1038 1042 msgstr "Salvar conteúdo da tela"
1039 1043  
... ... @@ -1061,7 +1065,7 @@ msgstr &quot;Guarda fila de transferência num arquivo XML externo&quot;
1061 1065 msgid "Save transfer queue to file"
1062 1066 msgstr "Salvar fila de transferências para arquivo"
1063 1067  
1064   -#: src/dialogs/settings/clipboard.c:375
  1068 +#: src/dialogs/settings/clipboard.c:386
1065 1069 msgid "Screen with terminal attributes"
1066 1070 msgstr "Completa incluindo atributos do terminal"
1067 1071  
... ... @@ -1086,7 +1090,7 @@ msgid &quot;Secondary space&quot;
1086 1090 msgstr "Secondary space"
1087 1091  
1088 1092 #: src/filetransfer/v3270ft.c:303 src/filetransfer/settings.c:209
1089   -#: src/dialogs/save/save.c:114 src/dialogs/save/save.c:137
  1093 +#: src/dialogs/save/save.c:98 src/dialogs/save/save.c:118
1090 1094 #: src/dialogs/settings/host.c:402
1091 1095 msgid "Select"
1092 1096 msgstr "Selecionar"
... ... @@ -1099,13 +1103,13 @@ msgstr &quot;Selecionar arquivo com mapeamento personalizado&quot;
1099 1103 msgid "Select custom charset mapping"
1100 1104 msgstr "Seleciona mapeamento de teclado personalizado"
1101 1105  
1102   -#: src/dialogs/save/save.c:113 src/dialogs/save/save.c:133
  1106 +#: src/dialogs/save/save.c:97 src/dialogs/save/save.c:114
1103 1107 msgid "Select destination file"
1104 1108 msgstr "Selecionar arquivo destino"
1105 1109  
1106 1110 #: src/filetransfer/v3270ft.c:591 src/filetransfer/settings.c:467
1107 1111 #: src/dialogs/load.c:92 src/dialogs/load.c:108 src/dialogs/load.c:171
1108   -#: src/dialogs/save/save.c:205
  1112 +#: src/dialogs/save/save.c:258
1109 1113 msgid "Select file"
1110 1114 msgstr "Selecionar arquivo"
1111 1115  
... ... @@ -1245,7 +1249,7 @@ msgstr &quot;Tipo de situação&quot;
1245 1249 msgid "State of the dynamic font spacing"
1246 1250 msgstr "Estado do espaçamento dinâmico"
1247 1251  
1248   -#: src/dialogs/settings/accelerator.c:171
  1252 +#: src/dialogs/settings/accelerator.c:176
1249 1253 msgid "Summary"
1250 1254 msgstr "Sumário"
1251 1255  
... ... @@ -1288,11 +1292,11 @@ msgstr &quot;&quot;
1288 1292 "has been reached, or the maximum number of data blocks per file (16060) has "
1289 1293 "been reached."
1290 1294  
1291   -#: src/dialogs/settings/host.c:616
  1295 +#: src/dialogs/settings/host.c:645
1292 1296 msgid "The EBCDIC host character set. "
1293 1297 msgstr "A tabela de caracteres EBCDIC."
1294 1298  
1295   -#: src/dialogs/settings/accelerator.c:450
  1299 +#: src/dialogs/settings/accelerator.c:455
1296 1300 #, c-format
1297 1301 msgid "The action \"%s\" can't manage alternative keys"
1298 1302 msgstr "A ação \"%s\" não permite uso de atalho alternativo"
... ... @@ -1313,12 +1317,7 @@ msgstr &quot;&quot;
1313 1317 "Tabela de callbacks para transferência de arquivos inválida, possível "
1314 1318 "divergência de versão na lib3270"
1315 1319  
1316   -#: src/terminal/callbacks.c:391
1317   -#, c-format
1318   -msgid "The error code was %d"
1319   -msgstr "O código de erro foi %d"
1320   -
1321   -#: src/dialogs/save/save.c:415
  1320 +#: src/dialogs/save/save.c:425
1322 1321 #, c-format
1323 1322 msgid "The file \"%s\" already exists. Replace it?"
1324 1323 msgstr "O arquivo \"%s\" já existe, substituir?"
... ... @@ -1377,12 +1376,12 @@ msgstr &quot;Operação de impressão está em andamento&quot;
1377 1376 msgid "The print settings should be stored."
1378 1377 msgstr "Configuração de impressão deve ser armazenada"
1379 1378  
1380   -#: src/dialogs/settings/accelerator.c:304
  1379 +#: src/dialogs/settings/accelerator.c:309
1381 1380 #, c-format
1382 1381 msgid "The selected accelerator is in use by action <b>%s</b> (<b>%s</b>)"
1383 1382 msgstr "O atalho selecionado está em uso pela ação <b>%s</b> (<b>%s</b>)"
1384 1383  
1385   -#: src/dialogs/settings/accelerator.c:324
  1384 +#: src/dialogs/settings/accelerator.c:329
1386 1385 msgid "The selected accelerator is in use by the same action"
1387 1386 msgstr "O atalho selecionado está em uso na mesma ação"
1388 1387  
... ... @@ -1464,10 +1463,14 @@ msgstr &quot;Fila de transferências&quot;
1464 1463 msgid "Transfer speed"
1465 1464 msgstr "Velocidade de transferência"
1466 1465  
1467   -#: src/terminal/properties/init.c:250
  1466 +#: src/terminal/properties/init.c:249
1468 1467 msgid "True if the terminal has copy blocks"
1469 1468 msgstr "Verdadeiro se o terminal tiver blocos copiados"
1470 1469  
  1470 +#: src/terminal/properties/init.c:264
  1471 +msgid "True if the timer indicator is active"
  1472 +msgstr "Verdadeiro se indicador de tempo estiver ativo"
  1473 +
1471 1474 #: src/filetransfer/transfer.c:84
1472 1475 msgid "Try again with the same file."
1473 1476 msgstr "Tente de novo com o mesmo arquivo."
... ... @@ -1480,20 +1483,25 @@ msgstr &quot;Turquesa&quot;
1480 1483 msgid "UTF-8"
1481 1484 msgstr "UTF-8"
1482 1485  
1483   -#: src/selection/windows/paste.c:115
1484   -msgid "Unable to paste formatted data"
1485   -msgstr "Incapaz de colar tela formatada."
  1486 +#: src/selection/linux/paste.c:116
  1487 +msgid "Unable to paste formatted data."
  1488 +msgstr "Incapaz de colar dados formatados."
1486 1489  
1487 1490 #: src/filetransfer/tables.c:92
1488 1491 msgid "Undefined"
1489 1492 msgstr "Indefinido"
1490 1493  
1491   -#: src/dialogs/save/save.c:400
  1494 +#: src/terminal/callbacks.c:472
  1495 +#, c-format
  1496 +msgid "Unexpected callback table, the release %s of lib%s is invalid"
  1497 +msgstr "Tabela de callbacks inesperada, a revisão %s da lib%s é inválida"
  1498 +
  1499 +#: src/dialogs/save/save.c:495
1492 1500 #, c-format
1493 1501 msgid "Unexpected format %d"
1494 1502 msgstr "Formato inesperado %d"
1495 1503  
1496   -#: src/dialogs/save/save.c:370
  1504 +#: src/dialogs/save/save.c:463 src/dialogs/save/save.c:559
1497 1505 #, c-format
1498 1506 msgid "Unexpected mode %d"
1499 1507 msgstr "Modo inesperado %d"
... ... @@ -1503,7 +1511,11 @@ msgstr &quot;Modo inesperado %d&quot;
1503 1511 msgid "Unexpected status %d in print operation"
1504 1512 msgstr "Estado inesperado %d na operação de impressão"
1505 1513  
1506   -#: src/dialogs/windows/select.c:169 src/dialogs/save/save.c:149
  1514 +#: src/dialogs/settings/host.c:559
  1515 +msgid "Unsecure"
  1516 +msgstr "Insegura"
  1517 +
  1518 +#: src/dialogs/save/save.c:130
1507 1519 msgid "Untitled document"
1508 1520 msgstr "Documento sem título"
1509 1521  
... ... @@ -1524,6 +1536,10 @@ msgstr &quot;Variável&quot;
1524 1536 msgid "Western Europe (ISO 8859-1)"
1525 1537 msgstr "Europa ocidental (ISO 8859-1)"
1526 1538  
  1539 +#: src/dialogs/settings/clipboard.c:174
  1540 +msgid "When set allow image formats on clipboard"
  1541 +msgstr "Quando ativo permite imagens na área de transferência"
  1542 +
1527 1543 #: src/dialogs/settings/clipboard.c:154
1528 1544 msgid ""
1529 1545 "When set search clipboard for a similar screen, if found paste unprotected "
... ... @@ -1705,20 +1721,21 @@ msgstr &quot;Texto _ASCII&quot;
1705 1721 msgid "_Apply"
1706 1722 msgstr "_Aplicar"
1707 1723  
1708   -#: src/selection/windows/paste.c:83 src/selection/windows/paste.c:123
1709   -#: src/dialogs/load.c:205 src/dialogs/load.c:224
1710   -#: src/dialogs/windows/select.c:158 src/dialogs/print/settingsdialog.c:410
1711   -#: src/dialogs/print/settingsdialog.c:429 src/dialogs/save/save.c:267
1712   -#: src/dialogs/save/save.c:286 src/dialogs/settings/dialog.c:231
  1724 +#: src/selection/linux/paste.c:85 src/dialogs/popups.c:157
  1725 +#: src/dialogs/load.c:205 src/dialogs/load.c:224 src/dialogs/linux/select.c:51
  1726 +#: src/dialogs/linux/select.c:77 src/dialogs/print/settingsdialog.c:410
  1727 +#: src/dialogs/print/settingsdialog.c:429 src/dialogs/save/save.c:342
  1728 +#: src/dialogs/save/save.c:361 src/dialogs/settings/dialog.c:231
1713 1729 msgid "_Cancel"
1714 1730 msgstr "_Cancelar"
1715 1731  
1716   -#: src/dialogs/settings/host.c:615
  1732 +#: src/dialogs/settings/host.c:644
1717 1733 msgid "_Charset"
1718 1734 msgstr "Tabela de _Caracteres"
1719 1735  
1720 1736 #: src/trace/tracewindow.c:125 src/dialogs/transfer.c:163
1721 1737 #: src/dialogs/transfer.c:183 src/dialogs/security.c:235
  1738 +#: src/dialogs/popups.c:95
1722 1739 msgid "_Close"
1723 1740 msgstr "_Close"
1724 1741  
... ... @@ -1730,7 +1747,7 @@ msgstr &quot;_Tabela de cores&quot;
1730 1747 msgid "_File"
1731 1748 msgstr "_Arquivo"
1732 1749  
1733   -#: src/dialogs/load.c:163 src/dialogs/save/save.c:192
  1750 +#: src/dialogs/load.c:163 src/dialogs/save/save.c:250
1734 1751 msgid "_Filename"
1735 1752 msgstr "Nome do _Arquivo"
1736 1753  
... ... @@ -1754,11 +1771,16 @@ msgstr &quot;Arquivo _local:&quot;
1754 1771 msgid "_Model"
1755 1772 msgstr "_Modelo"
1756 1773  
  1774 +#: src/dialogs/popups.c:77 src/dialogs/popups.c:83 src/dialogs/popups.c:89
  1775 +#: src/dialogs/popups.c:101
  1776 +msgid "_Ok"
  1777 +msgstr "_Ok"
  1778 +
1757 1779 #: src/filetransfer/v3270ft.c:333
1758 1780 msgid "_Operation"
1759 1781 msgstr "_Operação:"
1760 1782  
1761   -#: src/selection/windows/paste.c:84 src/selection/windows/paste.c:124
  1783 +#: src/selection/linux/paste.c:86 src/selection/linux/paste.c:118
1762 1784 msgid "_Paste as text"
1763 1785 msgstr "_Colar como texto"
1764 1786  
... ... @@ -1766,14 +1788,14 @@ msgstr &quot;_Colar como texto&quot;
1766 1788 msgid "_Remote file"
1767 1789 msgstr "Arquivo _remoto:"
1768 1790  
1769   -#: src/trace/tracewindow.c:123 src/dialogs/save/save.c:272
1770   -#: src/dialogs/save/save.c:287
  1791 +#: src/trace/tracewindow.c:123 src/dialogs/save/save.c:347
  1792 +#: src/dialogs/save/save.c:362
1771 1793 msgid "_Save"
1772 1794 msgstr "_Salvar"
1773 1795  
1774 1796 #: src/dialogs/settings/host.c:545
1775   -msgid "_Secure connection."
1776   -msgstr "Conexão _Segura."
  1797 +msgid "_Security"
  1798 +msgstr "_Segurança"
1777 1799  
1778 1800 #: src/dialogs/settings/host.c:228
1779 1801 msgid "_Service"
... ... @@ -2305,6 +2327,9 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2305 2327 #~ msgid "Charset has more than 256 entries"
2306 2328 #~ msgstr "Tabela de tradução tem mais de 256 caracteres"
2307 2329  
  2330 +#~ msgid "Check for SSL secure connection."
  2331 +#~ msgstr "Marcar para ativar a conexão segura via SSL."
  2332 +
2308 2333 #~ msgid "Check for text files."
2309 2334 #~ msgstr "Marque se o arquivo for texto."
2310 2335  
... ... @@ -2347,12 +2372,18 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2347 2372 #~ msgid "Connection state"
2348 2373 #~ msgstr "Estado da conexão"
2349 2374  
  2375 +#~ msgid "Continue"
  2376 +#~ msgstr "Continuar"
  2377 +
2350 2378 #~ msgid "Copiar tudo"
2351 2379 #~ msgstr "Copiar tudo"
2352 2380  
2353 2381 #~ msgid "Copy as HTML"
2354 2382 #~ msgstr "Copiar como HTML"
2355 2383  
  2384 +#~ msgid "Critical Error"
  2385 +#~ msgstr "Erro crítico"
  2386 +
2356 2387 #, fuzzy
2357 2388 #~ msgid "Cross hair Cursor"
2358 2389 #~ msgstr "Cursor mira"
... ... @@ -2490,6 +2521,9 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2490 2521 #~ msgid "Erase to end of line"
2491 2522 #~ msgstr "Apagar até o final da linha"
2492 2523  
  2524 +#~ msgid "Error"
  2525 +#~ msgstr "Erro"
  2526 +
2493 2527 #~ msgid "Error \"%s\" reading from local file (rc=%d)"
2494 2528 #~ msgstr "Erro \"%s\" lendo arquivo local (rc=%d)"
2495 2529  
... ... @@ -2511,9 +2545,6 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2511 2545 #~ msgid "Error in ioctl(%s) when setting no blocking mode"
2512 2546 #~ msgstr "Erro em ioctl(%s) ao ativar o modo não blocante"
2513 2547  
2514   -#~ msgid "Error loading %s"
2515   -#~ msgstr "Erro lendo %s"
2516   -
2517 2548 #~ msgid "Error loading CRL"
2518 2549 #~ msgstr "Erro lendo CRL"
2519 2550  
... ... @@ -2750,8 +2781,8 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2750 2781 #~ msgid "Incorrect request code: file transfer canceled"
2751 2782 #~ msgstr "Código de requisição incorreto, transferência cancelada"
2752 2783  
2753   -#~ msgid "Informations"
2754   -#~ msgstr "Informações"
  2784 +#~ msgid "Information"
  2785 +#~ msgstr "Informação"
2755 2786  
2756 2787 #~ msgid "Input method"
2757 2788 #~ msgstr "Método de entrada"
... ... @@ -2774,6 +2805,10 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2774 2805 #~ msgid "Invalid argument format"
2775 2806 #~ msgstr "O formato do argumento é inválido"
2776 2807  
  2808 +#~ msgid "Invalid callback table, possible version mismatch in lib3270"
  2809 +#~ msgstr ""
  2810 +#~ "Tabela de callbacks inválida, possível divergência de versão na lib3270"
  2811 +
2777 2812 #~ msgid "Invalid character value"
2778 2813 #~ msgstr "Valor de caractere inválido"
2779 2814  
... ... @@ -2927,9 +2962,6 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2927 2962 #~ msgid "Non zero if the host is TSO."
2928 2963 #~ msgstr "Diferente de zero se o host é TSO"
2929 2964  
2930   -#~ msgid "None of the screens in the clipboard match with the current one."
2931   -#~ msgstr "Nenhuma das telas da área de transferência corresponde à atual."
2932   -
2933 2965 #~ msgid "Not available"
2934 2966 #~ msgstr "Não disponível"
2935 2967  
... ... @@ -2942,6 +2974,9 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
2942 2974 #~ "Permitida apenas uma opção dentre TRACKS, CYLINDERS, AVBLOCK: "
2943 2975 #~ "Transferência cancelada"
2944 2976  
  2977 +#~ msgid "Operation failed"
  2978 +#~ msgstr "Operação falhou"
  2979 +
2945 2980 #~ msgid "Option '%c:' is not supported"
2946 2981 #~ msgstr "Opção não suportada: '%c:'"
2947 2982  
... ... @@ -3339,9 +3374,6 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
3339 3374 #~ msgid "Secure connection was successful."
3340 3375 #~ msgstr "Conexão segura efetuada com sucesso."
3341 3376  
3342   -#~ msgid "Security error"
3343   -#~ msgstr "Erro de segurança"
3344   -
3345 3377 #~ msgid "Security warning"
3346 3378 #~ msgstr "Alerta de segurança"
3347 3379  
... ... @@ -3652,6 +3684,9 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
3652 3684 #~ "Intervalo de tempo entre o desbloqueio de teclado pelo host e o "
3653 3685 #~ "desbloqueio real"
3654 3686  
  3687 +#~ msgid "The error code was %d"
  3688 +#~ msgstr "O código de erro foi %d"
  3689 +
3655 3690 #~ msgid "The height %d is less than model %d rows (%d)"
3656 3691 #~ msgstr "A altura %d é menor que o número de linhas do modelo %d (%d)"
3657 3692  
... ... @@ -3995,6 +4030,9 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
3995 4030 #~ msgid "Waiting for PUT response"
3996 4031 #~ msgstr "Aguardando resposta do pedido de upload"
3997 4032  
  4033 +#~ msgid "Warning"
  4034 +#~ msgstr "Alerta"
  4035 +
3998 4036 #~ msgid "Where to save the received file."
3999 4037 #~ msgstr "Onde salvar o arquivo recebido."
4000 4038  
... ... @@ -4040,6 +4078,9 @@ msgstr &quot;Diminui o tamanho da fonte&quot;
4040 4078 #~ msgid "_Receive"
4041 4079 #~ msgstr "_Receber"
4042 4080  
  4081 +#~ msgid "_Secure connection."
  4082 +#~ msgstr "Conexão _Segura."
  4083 +
4043 4084 #~ msgid "_Send"
4044 4085 #~ msgstr "_Enviar"
4045 4086  
... ...
src/dialogs/popups.c
... ... @@ -32,182 +32,204 @@
32 32 #include <terminal.h>
33 33 #include <v3270/dialogs.h>
34 34 #include <v3270/settings.h>
  35 + #include <lib3270/popup.h>
35 36  
36 37 /*--[ Implement ]------------------------------------------------------------------------------------*/
37 38  
38   - void v3270_popup_message(GtkWidget *widget, LIB3270_NOTIFY type , const gchar *title, const gchar *message, const gchar *text) {
39   - GtkWidget * dialog;
40   - GtkWidget * toplevel = NULL;
41   - GtkMessageType msgtype = GTK_MESSAGE_WARNING;
42   - GtkButtonsType buttons = GTK_BUTTONS_OK;
  39 + GtkResponseType v3270_popup_dialog_show(GtkWidget *widget, const LIB3270_POPUP *popup, gboolean wait) {
43 40  
44   - if(widget && GTK_IS_WIDGET(widget))
45   - toplevel = gtk_widget_get_toplevel(GTK_WIDGET(widget));
  41 + g_return_val_if_fail(GTK_IS_WIDGET(widget),GTK_RESPONSE_NONE);
46 42  
47   - if(!GTK_IS_WINDOW(toplevel))
48   - toplevel = NULL;
  43 + // Check if the dialog is enabled
  44 + gboolean allow_disabling = (popup->name && GTK_IS_V3270(widget));
49 45  
50   - if(type == LIB3270_NOTIFY_CRITICAL) {
51   - msgtype = GTK_MESSAGE_ERROR;
52   - buttons = GTK_BUTTONS_CLOSE;
53   - }
  46 + debug("%s: name=%s allow-disabling: %s", __FUNCTION__, popup->name, allow_disabling ? "Yes" : "No");
54 47  
55   - if(!title)
56   - title = _( "Error" );
57   -
58   - if(message) {
59   - dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(toplevel),GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,msgtype,buttons,"%s",message);
60   - if(text && *text)
61   - gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog),"%s",text);
62   - } else if(text && *text) {
63   - dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(toplevel),GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,msgtype,buttons,"%s",text);
64   - } else {
65   - dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(toplevel),GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,msgtype,buttons,"%s",title);
66   - }
  48 + if(allow_disabling) {
67 49  
68   - gtk_window_set_title(GTK_WINDOW(dialog),title);
69   - gtk_widget_show_all(dialog);
70   - gtk_dialog_run(GTK_DIALOG (dialog));
71   - gtk_widget_destroy(dialog);
  50 + GtkResponseType response = 0;
72 51  
73   - }
  52 + debug("Emitting %s","V3270_SIGNAL_LOAD_POPUP_RESPONSE");
  53 + v3270_signal_emit(
  54 + widget,
  55 + V3270_SIGNAL_LOAD_POPUP_RESPONSE,
  56 + popup->name,
  57 + &response
  58 + );
74 59  
75   - void v3270_error_popup(GtkWidget *widget, const gchar *title, const gchar *summary, const gchar *body) {
76   - GtkWidget * dialog =
77   - gtk_message_dialog_new_with_markup(
78   - GTK_WINDOW(gtk_widget_get_toplevel(widget)),
79   - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
80   - GTK_MESSAGE_ERROR,
81   - GTK_BUTTONS_CLOSE,
82   - "%s",summary
83   - );
  60 + debug("Got response %d",(int) response);
84 61  
85   - gtk_window_set_title(GTK_WINDOW(dialog), (title ? title : _("Error")));
  62 + if(response && response != GTK_RESPONSE_NONE)
  63 + return response;
86 64  
87   - if(body)
88   - gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog),"%s",body);
  65 + allow_disabling = (response == GTK_RESPONSE_NONE);
  66 + }
89 67  
90   - g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL);
91   - g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
  68 + // Popup settings.
  69 + static const struct _settings {
  70 + GtkMessageType type;
  71 + const gchar *button;
  72 + } settings[LIB3270_NOTIFY_USER] = {
  73 +
  74 + // LIB3270_NOTIFY_INFO - Simple information dialog.
  75 + {
  76 + .type = GTK_MESSAGE_INFO,
  77 + .button = N_("_Ok"),
  78 + },
  79 +
  80 + // LIB3270_NOTIFY_WARNING - Warning message.
  81 + {
  82 + .type = GTK_MESSAGE_WARNING,
  83 + .button = N_("_Ok"),
  84 + },
  85 +
  86 + // LIB3270_NOTIFY_ERROR - Error message.
  87 + {
  88 + .type = GTK_MESSAGE_ERROR,
  89 + .button = N_("_Ok"),
  90 + },
  91 +
  92 + // LIB3270_NOTIFY_CRITICAL - Critical error, user can abort application.
  93 + {
  94 + .type = GTK_MESSAGE_ERROR,
  95 + .button = N_("_Close"),
  96 + },
  97 +
  98 + // LIB3270_NOTIFY_SECURE - Secure host dialog.
  99 + {
  100 + .type = GTK_MESSAGE_OTHER,
  101 + .button = N_("_Ok"),
  102 + }
92 103  
93   - gtk_widget_show_all(dialog);
  104 + };
94 105  
95   - }
  106 + // Create dialog
  107 + GtkWidget * dialog =
  108 + gtk_message_dialog_new_with_markup(
  109 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  110 + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
  111 + settings[popup->type].type,
  112 + GTK_BUTTONS_NONE,
  113 + (popup->body ? "<b><big>%s</big></b>" : "%s"),
  114 + popup->summary
  115 + );
96 116  
97   - void v3270_popup_gerror(GtkWidget *widget, GError *error, const gchar *title, const gchar *fmt, ...) {
  117 + if(popup->body) {
  118 + gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog),"<small>%s</small>",popup->body);
  119 + }
98 120  
99   - // Format message.
100   - va_list arg_ptr;
101   - va_start(arg_ptr, fmt);
102   - g_autofree gchar *text = g_strdup_vprintf(fmt,arg_ptr);
103   - va_end(arg_ptr);
  121 + if(popup->title) {
  122 + gtk_window_set_title(GTK_WINDOW(dialog),popup->title);
  123 + }
104 124  
105   - GtkWidget *dialog = gtk_message_dialog_new(
106   - GTK_WINDOW(gtk_widget_get_toplevel(widget)),
107   - GTK_DIALOG_DESTROY_WITH_PARENT,
108   - GTK_MESSAGE_ERROR,
109   - GTK_BUTTONS_OK,
110   - "%s",text
111   - );
  125 + if(wait) {
112 126  
113   - if(title)
114   - gtk_window_set_title(GTK_WINDOW(dialog), title);
115   - else
116   - gtk_window_set_title(GTK_WINDOW(dialog), (title ? title : _("Operation failed")));
  127 + GtkWidget * dont_ask = NULL;
117 128  
118   - if(error)
119   - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",error->message);
  129 + if(allow_disabling) {
  130 + // Set check button
  131 + dont_ask = gtk_check_button_new_with_label(_("Don't ask again"));
120 132  
121   - g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL);
122   - g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
  133 + gtk_widget_set_can_focus(dont_ask,FALSE);
  134 + gtk_widget_set_can_default(dont_ask,FALSE);
123 135  
124   - gtk_widget_show_all(dialog);
  136 +#if GTK_CHECK_VERSION(3,20,0)
  137 + gtk_widget_set_focus_on_click(dont_ask,FALSE);
  138 +#endif // GTK 3,20,0
125 139  
126   - }
  140 + gtk_widget_set_valign(dont_ask, GTK_ALIGN_BASELINE);
  141 + gtk_widget_set_halign(dont_ask, GTK_ALIGN_START);
127 142  
128   - GtkResponseType v3270_popup_toggleable_dialog(GtkWidget *widget, V3270_TOGGLEABLE_DIALOG id, const gchar *title, const gchar *summary, const gchar *body, const gchar *first_button_text, ...) {
  143 + gtk_box_pack_start(
  144 + GTK_BOX(gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog))),
  145 + dont_ask,
  146 + TRUE,
  147 + TRUE,
  148 + 0
  149 + );
  150 + }
129 151  
130   - GtkResponseType response = GTK_V3270(widget)->responses[id];
  152 + // Wait for response.
  153 + if(popup->label) {
131 154  
132   - if(response == GTK_RESPONSE_NONE) {
133   - GtkWidget * dialog =
134   - gtk_message_dialog_new(
135   - GTK_WINDOW(gtk_widget_get_toplevel(widget)),
136   - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
137   - GTK_MESSAGE_INFO,
138   - GTK_BUTTONS_NONE,
139   - "%s",
140   - summary
  155 + gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
  156 + gtk_dialog_add_button(GTK_DIALOG(dialog), popup->label, GTK_RESPONSE_APPLY);
  157 + gtk_dialog_set_default_response(
  158 + GTK_DIALOG(dialog),
  159 + (popup->type == LIB3270_NOTIFY_SECURE ? GTK_RESPONSE_CANCEL : GTK_RESPONSE_APPLY)
141 160 );
142 161  
143   - if(body)
144   - gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog),"%s",body);
  162 + } else {
145 163  
146   - gtk_window_set_title(GTK_WINDOW(dialog),title);
  164 + gtk_dialog_add_button(GTK_DIALOG(dialog), g_dgettext(GETTEXT_PACKAGE,settings[popup->type].button), GTK_RESPONSE_OK);
147 165  
148   - // Set check button
149   - GtkWidget * dont_ask = gtk_check_button_new_with_label(_("Don't ask again"));
  166 + }
150 167  
151   - gtk_widget_set_can_focus(dont_ask,FALSE);
152   - gtk_widget_set_can_default(dont_ask,FALSE);
153   -#if GTK_CHECK_VERSION(3,20,0)
154   - gtk_widget_set_focus_on_click(dont_ask,FALSE);
155   -#endif // GTK 3,20,0
  168 + gtk_widget_show_all(dialog);
  169 + GtkResponseType rc = gtk_dialog_run(GTK_DIALOG(dialog));
156 170  
157   - gtk_widget_set_valign(dont_ask, GTK_ALIGN_BASELINE);
158   - gtk_widget_set_halign(dont_ask, GTK_ALIGN_START);
  171 + if(dont_ask && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dont_ask)) && rc != GTK_RESPONSE_DELETE_EVENT && rc != GTK_RESPONSE_NONE) {
159 172  
160   - gtk_box_pack_start(
161   - GTK_BOX(gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog))),
162   - dont_ask,
163   - TRUE,
164   - TRUE,
165   - 0
166   - );
  173 + gboolean saved = FALSE;
167 174  
168   - if(first_button_text) {
169   - // From https://github.com/GNOME/gtk/blob/master/gtk/gtkdialog.c
170   - va_list args;
171   - const gchar* text;
172   - gint response_id;
  175 + v3270_signal_emit(
  176 + widget,
  177 + V3270_SIGNAL_SAVE_POPUP_RESPONSE,
  178 + popup->name,
  179 + rc,
  180 + &saved
  181 + );
173 182  
174   - va_start(args, first_button_text);
  183 + debug("response was %s",saved ? "saved" : "not saved");
175 184  
176   - text = first_button_text;
177   - while(text) {
178   - response_id = va_arg(args, gint);
  185 + }
179 186  
180   - gtk_dialog_add_button(GTK_DIALOG(dialog), text, response_id);
  187 + gtk_widget_destroy(dialog);
  188 + return rc;
181 189  
182   - if(response_id == GTK_RESPONSE_APPLY || response_id == GTK_RESPONSE_OK || response_id == GTK_RESPONSE_YES)
183   - gtk_dialog_set_default_response(GTK_DIALOG(dialog),response_id);
  190 + }
184 191  
185   - text = va_arg(args, gchar*);
186   - }
  192 + // Unnamed dialog, no need for wait.
  193 + g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL);
  194 + g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
187 195  
188   - va_end (args);
189   - }
  196 + gtk_dialog_add_button(GTK_DIALOG(dialog), settings[popup->type].button, GTK_RESPONSE_OK);
190 197  
191   - gtk_widget_show_all(dialog);
192   - response = gtk_dialog_run(GTK_DIALOG(dialog));
  198 + gtk_widget_show_all(dialog);
193 199  
194   - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dont_ask))) {
  200 + return GTK_RESPONSE_NONE;
195 201  
196   - GTK_V3270(widget)->responses[id] = response;
197   - g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->responses[id]);
198   - v3270_emit_save_settings(widget);
  202 + }
199 203  
200   - debug(
201   - "Property %s is now %d",
202   - g_param_spec_get_name(GTK_V3270_GET_CLASS(widget)->responses[id]),
203   - GTK_V3270(widget)->responses[id]
204   - );
  204 + void v3270_error_popup(GtkWidget *widget, const gchar *title, const gchar *summary, const gchar *body) {
205 205  
206   - }
  206 + LIB3270_POPUP popup = {
  207 + .type = LIB3270_NOTIFY_ERROR,
  208 + .title = title,
  209 + .summary = summary,
  210 + .body = body
  211 + };
207 212  
208   - gtk_widget_destroy(dialog);
209   - }
  213 + v3270_popup_dialog_show(widget, &popup, FALSE);
  214 +
  215 + }
  216 +
  217 + void v3270_popup_gerror(GtkWidget *widget, GError *error, const gchar *title, const gchar *fmt, ...) {
  218 +
  219 + // Format message.
  220 + va_list arg_ptr;
  221 + va_start(arg_ptr, fmt);
  222 + g_autofree gchar *summary = g_strdup_vprintf(fmt,arg_ptr);
  223 + va_end(arg_ptr);
210 224  
211   - return response;
  225 + LIB3270_POPUP popup = {
  226 + .type = LIB3270_NOTIFY_ERROR,
  227 + .title = title,
  228 + .summary = summary,
  229 + .body = error->message
  230 + };
  231 +
  232 + v3270_popup_dialog_show(widget, &popup, FALSE);
212 233  
213 234 }
  235 +
... ...
src/dialogs/save/save.c
... ... @@ -91,22 +91,6 @@
91 91 #ifdef WIN32
92 92 static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, V3270SaveDialog *widget)
93 93 {
94   - /*
95   -
96   - GtkFileChooserNative * dialog =
97   - gtk_file_chooser_native_new(
98   - _( "Select destination file"),
99   - GTK_WINDOW(widget),
100   - GTK_FILE_CHOOSER_ACTION_SAVE,
101   - _("Select"),
102   - _("Cancel")
103   - );
104   -
105   - gint rc = gtk_native_dialog_run (GTK_NATIVE_DIALOG(dialog));
106   -
107   - debug("rc=%d",rc);
108   - */
109   -
110 94 g_autofree gchar *filename =
111 95 v3270_select_file(
112 96 GTK_WIDGET(widget),
... ... @@ -125,9 +109,6 @@ static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIco
125 109 static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, V3270SaveDialog *widget)
126 110 {
127 111  
128   - //gint format = gtk_combo_box_get_active(GTK_COMBO_BOX(widget->format));
129   - //g_autofree gchar * extension = g_strconcat("*",formats[format].extension,NULL);
130   -
131 112 GtkWidget * dialog =
132 113 gtk_file_chooser_dialog_new(
133 114 _( "Select destination file"),
... ... @@ -156,6 +137,83 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
156 137 }
157 138 #endif // _WIN32
158 139  
  140 +
  141 + static void filename_changed(GtkEntry *entry, GtkComboBox *formats)
  142 + {
  143 + const gchar * text = gtk_entry_get_text(entry);
  144 +
  145 + if(!(text && *text))
  146 + return;
  147 +
  148 + const gchar * extension = strrchr(text,'.');
  149 + if(!extension)
  150 + return;
  151 +
  152 + extension++;
  153 + const gchar * format = gtk_combo_box_get_active_id(formats);
  154 + if(*format == '.')
  155 + format++;
  156 +
  157 + if(g_ascii_strcasecmp(extension,format) == 0)
  158 + return;
  159 +
  160 + gint column = gtk_combo_box_get_id_column(formats);
  161 + GtkTreeModel * model = gtk_combo_box_get_model(formats);
  162 + GtkTreeIter iter;
  163 +
  164 + debug("id_column=%d",column);
  165 +
  166 + if(gtk_tree_model_get_iter_first(model,&iter))
  167 + {
  168 + do
  169 + {
  170 + g_autofree gchar *id = NULL;
  171 + gtk_tree_model_get(model, &iter, column, &id, -1);
  172 +
  173 + if(g_ascii_strcasecmp(extension,id + (*id == '.' ? 1 : 0)) == 0)
  174 + {
  175 + gtk_combo_box_set_active_iter(formats,&iter);
  176 + break;
  177 + }
  178 +
  179 + } while(gtk_tree_model_iter_next(model,&iter));
  180 + }
  181 +
  182 + }
  183 +
  184 + static void fileformat_changed(GtkComboBox *formats, GtkEntry *entry)
  185 + {
  186 + const gchar * text = gtk_entry_get_text(entry);
  187 +
  188 + if(!(text && *text))
  189 + return;
  190 +
  191 + gchar * extension = strrchr(text,'.');
  192 + if(!extension)
  193 + return;
  194 +
  195 + extension++;
  196 + const gchar * format = gtk_combo_box_get_active_id(formats);
  197 + if(*format == '.')
  198 + format++;
  199 +
  200 + if(g_ascii_strcasecmp(extension,format) == 0)
  201 + return;
  202 +
  203 + size_t szFilename = strlen(text) + strlen(format);
  204 + g_autofree gchar * filename = g_malloc0(szFilename + 1);
  205 +
  206 + strncpy(filename,text,szFilename);
  207 + extension = strrchr(filename,'.');
  208 + if(extension)
  209 + {
  210 + *(++extension) = 0;
  211 + strncat(filename, format + (*format == '.' ? 1 : 0),szFilename);
  212 + gtk_entry_set_text(entry,filename);
  213 + }
  214 +
  215 + }
  216 +
159 217 static void V3270SaveDialog_init(V3270SaveDialog *dialog)
160 218 {
161 219 // 0--------1---------------------2-------3--------------------4
... ... @@ -195,16 +253,10 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
195 253 gtk_grid_attach(grid,widget,0,0,1,1);
196 254 gtk_label_set_mnemonic_widget(GTK_LABEL(widget),dialog->filename);
197 255  
198   -//#ifdef WIN32
199   -// widget = gtk_button_new_from_icon_name("document-open",GTK_ICON_SIZE_BUTTON);
200   -// g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(select_file),dialog);
201   -// gtk_grid_attach(grid,widget,4,0,1,1);
202   -//#else
203   - gtk_entry_set_icon_from_icon_name(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,"document-open");
  256 + gtk_entry_set_icon_from_icon_name(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,"document-save-as");
204 257 gtk_entry_set_icon_activatable(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,TRUE);
205 258 gtk_entry_set_icon_tooltip_text(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,_("Select file"));
206 259 g_signal_connect(G_OBJECT(dialog->filename),"icon-press",G_CALLBACK(icon_press),dialog);
207   -//#endif // WIN32
208 260  
209 261 gtk_entry_set_width_chars(GTK_ENTRY(dialog->filename),60);
210 262 gtk_entry_set_max_length(GTK_ENTRY(dialog->filename),PATH_MAX);
... ... @@ -240,7 +292,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
240 292 {
241 293 gtk_combo_box_text_insert(
242 294 GTK_COMBO_BOX_TEXT(dialog->format),
243   - ix,
  295 + -1,
244 296 formats[ix].extension,
245 297 g_dgettext(GETTEXT_PACKAGE,formats[ix].name)
246 298 );
... ... @@ -248,6 +300,29 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
248 300  
249 301 gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->format),0);
250 302  
  303 + // Image formats.
  304 + GSList *img_formats = gdk_pixbuf_get_formats();
  305 + GSList *img_format;
  306 +
  307 + for(img_format = img_formats;img_format;img_format = g_slist_next(img_format))
  308 + {
  309 + GdkPixbufFormat * pixFormat = (GdkPixbufFormat *) img_format->data;
  310 +
  311 + if (gdk_pixbuf_format_is_writable(pixFormat))
  312 + {
  313 + gtk_combo_box_text_insert(
  314 + GTK_COMBO_BOX_TEXT(dialog->format),
  315 + -1,
  316 + gdk_pixbuf_format_get_name(pixFormat),
  317 + gdk_pixbuf_format_get_description(pixFormat)
  318 + );
  319 + }
  320 +
  321 + }
  322 +
  323 + g_signal_connect(dialog->filename,"changed",G_CALLBACK(filename_changed),dialog->format);
  324 + g_signal_connect(dialog->format,"changed",G_CALLBACK(fileformat_changed),dialog->filename);
  325 +
251 326 }
252 327  
253 328  
... ... @@ -335,20 +410,38 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
335 410 return GTK_WIDGET(dialog);
336 411 }
337 412  
338   - void v3270_save_dialog_apply(GtkWidget *widget, GError **error)
  413 + static const gchar * get_filename(V3270SaveDialog * dialog)
339 414 {
340   - V3270SaveDialog * dialog = V3270_SAVE_DIALOG(widget);
  415 + const gchar * filename = gtk_entry_get_text(GTK_ENTRY(dialog->filename));
  416 + gint response = GTK_RESPONSE_OK;
341 417  
342   - if(!v3270_is_connected(dialog->terminal))
  418 + if(g_file_test(filename,G_FILE_TEST_EXISTS))
343 419 {
344   - *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENOTCONN));
345   - return;
  420 + GtkWidget * confirmation =
  421 + gtk_message_dialog_new_with_markup(
  422 + GTK_WINDOW(dialog),
  423 + GTK_DIALOG_DESTROY_WITH_PARENT,
  424 + GTK_MESSAGE_QUESTION,GTK_BUTTONS_OK_CANCEL,
  425 + _("The file \"%s\" already exists. Replace it?"),
  426 + filename
  427 + );
  428 +
  429 + response = gtk_dialog_run(GTK_DIALOG(confirmation));
  430 + gtk_widget_destroy(confirmation);
346 431 }
347 432  
  433 + return (response == GTK_RESPONSE_OK ? filename : NULL);
  434 +
  435 + }
  436 +
  437 + static void save_as_text(V3270SaveDialog * dialog, size_t index, GError **error)
  438 + {
348 439 // Get selection
349 440 GList * dynamic = NULL;
350 441 const GList * selection = NULL;
351 442  
  443 + debug("%s(%d)",__FUNCTION__,dialog->mode);
  444 +
352 445 switch(dialog->mode)
353 446 {
354 447 case LIB3270_CONTENT_ALL:
... ... @@ -371,6 +464,8 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
371 464 return;
372 465 }
373 466  
  467 + debug("Selection=%p",selection);
  468 +
374 469 if(!selection)
375 470 {
376 471 *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENODATA));
... ... @@ -382,7 +477,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
382 477  
383 478 debug("Encoding: %s",encoding);
384 479  
385   - switch(gtk_combo_box_get_active(GTK_COMBO_BOX(dialog->format)))
  480 + switch(index)
386 481 {
387 482 case 0: // "Plain text"
388 483 text = v3270_get_selection_as_text(GTK_V3270(dialog->terminal), selection, encoding, dialog->mode == LIB3270_CONTENT_ALL);
... ... @@ -402,25 +497,9 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
402 497  
403 498 if(text)
404 499 {
405   - const gchar * filename = gtk_entry_get_text(GTK_ENTRY(dialog->filename));
406   - gint response = GTK_RESPONSE_OK;
  500 + const gchar * filename = get_filename(dialog);
407 501  
408   - if(g_file_test(filename,G_FILE_TEST_EXISTS))
409   - {
410   - GtkWidget * confirmation =
411   - gtk_message_dialog_new_with_markup(
412   - GTK_WINDOW(widget),
413   - GTK_DIALOG_DESTROY_WITH_PARENT,
414   - GTK_MESSAGE_QUESTION,GTK_BUTTONS_OK_CANCEL,
415   - _("The file \"%s\" already exists. Replace it?"),
416   - filename
417   - );
418   -
419   - response = gtk_dialog_run(GTK_DIALOG(confirmation));
420   - gtk_widget_destroy(confirmation);
421   - }
422   -
423   - if(response == GTK_RESPONSE_OK)
  502 + if(filename)
424 503 {
425 504 g_file_set_contents(
426 505 gtk_entry_get_text(GTK_ENTRY(dialog->filename)),
... ... @@ -445,6 +524,93 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_
445 524 #pragma GCC diagnostic pop
446 525 }
447 526  
  527 + static void save_as_image(V3270SaveDialog * dialog, const gchar *format, GError **error)
  528 + {
  529 + debug("%s(%d)",__FUNCTION__,dialog->mode);
  530 +
  531 + GdkPixbuf * pixbuf = NULL;
  532 +
  533 + switch(dialog->mode)
  534 + {
  535 + case LIB3270_CONTENT_ALL:
  536 + debug("%s","LIB3270_CONTENT_ALL");
  537 + pixbuf = v3270_get_as_pixbuf(dialog->terminal);
  538 + break;
  539 +
  540 + case LIB3270_CONTENT_COPY:
  541 + {
  542 + debug("%s","LIB3270_CONTENT_COPY");
  543 + const GList * selection = v3270_get_selection_blocks(dialog->terminal);
  544 + pixbuf = v3270_get_selection_as_pixbuf(GTK_V3270(dialog->terminal), selection, FALSE);
  545 + }
  546 + break;
  547 +
  548 + case LIB3270_CONTENT_SELECTED:
  549 + {
  550 + debug("%s","LIB3270_CONTENT_SELECTED");
  551 + GList * selection = g_list_append_lib3270_selection(NULL, v3270_get_session(dialog->terminal),FALSE);
  552 + debug("Selection=%p",selection);
  553 + pixbuf = v3270_get_selection_as_pixbuf(GTK_V3270(dialog->terminal), selection, FALSE);
  554 + g_list_free_full(selection,(GDestroyNotify) lib3270_free);
  555 + }
  556 + break;
  557 +
  558 + default:
  559 + *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,_( "Unexpected mode %d" ),(int) dialog->mode);
  560 + return;
  561 + }
  562 +
  563 + debug("pixbuff=%p",pixbuf);
  564 +
  565 + if(pixbuf)
  566 + {
  567 + const gchar * filename = get_filename(dialog);
  568 +
  569 + debug("Filename=%p",filename);
  570 + if(filename)
  571 + {
  572 + gdk_pixbuf_save(pixbuf,filename,format,error,NULL);
  573 + }
  574 +
  575 + g_object_unref(pixbuf);
  576 + }
  577 + else
  578 + {
  579 + *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),-1,_( "Error saving image" ));
  580 + }
  581 +
  582 + }
  583 +
  584 + void v3270_save_dialog_apply(GtkWidget *widget, GError **error)
  585 + {
  586 + size_t ix;
  587 + V3270SaveDialog * dialog = V3270_SAVE_DIALOG(widget);
  588 +
  589 + if(!v3270_is_connected(dialog->terminal))
  590 + {
  591 + *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENOTCONN));
  592 + return;
  593 + }
  594 +
  595 + // Get type ID
  596 + const gchar * format = gtk_combo_box_get_active_id(GTK_COMBO_BOX(dialog->format));
  597 +
  598 + // Check for text formats.
  599 + for(ix=0;ix<G_N_ELEMENTS(formats);ix++)
  600 + {
  601 + if(!strcmp(formats[ix].extension,format))
  602 + {
  603 + // Is text format, save it
  604 + save_as_text(dialog, ix, error);
  605 + return;
  606 + }
  607 +
  608 + }
  609 +
  610 + save_as_image(dialog, format, error);
  611 +
  612 + }
  613 +
448 614 void v3270_save_dialog_run(GtkWidget *widget)
449 615 {
450 616 if(gtk_dialog_run(GTK_DIALOG(widget)) == GTK_RESPONSE_APPLY)
... ...
src/dialogs/settings/accelerator.c
... ... @@ -140,6 +140,11 @@
140 140 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(widget->store),1,GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID);
141 141  
142 142 GtkWidget * view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(widget->store));
  143 +
  144 + gtk_tree_view_set_enable_search(GTK_TREE_VIEW(view),TRUE);
  145 + gtk_tree_view_set_search_column(GTK_TREE_VIEW(view),1);
  146 +
  147 +
143 148 g_signal_connect(G_OBJECT(widget),"realize",G_CALLBACK(realize),view);
144 149  
145 150 gtk_widget_set_tooltip_markup(view,_("Keyboard accelerators"));
... ...
src/dialogs/settings/clipboard.c
... ... @@ -163,11 +163,22 @@
163 163 .label = N_("Smart copy"),
164 164 .tooltip = N_("When set the first copy operation after the selection will set the clipboard contents and the next ones will append"),
165 165 .left = 1,
  166 + .top = 4,
  167 + .width = 1,
  168 + .height = 1,
  169 + .grid = COPY_SETTINGS
  170 + },
  171 +
  172 + {
  173 + .label = N_("Image copy"),
  174 + .tooltip = N_("When set allow image formats on clipboard"),
  175 + .left = 1,
166 176 .top = 3,
167 177 .width = 1,
168 178 .height = 1,
169 179 .grid = COPY_SETTINGS
170 180 }
  181 +
171 182 };
172 183  
173 184 /*--[ Globals ]--------------------------------------------------------------------------------------*/
... ... @@ -472,6 +483,7 @@ static void load(GtkWidget *w, GtkWidget *t) {
472 483 gtk_toggle_button_set_active(widget->input.checkboxes[0],(terminal->selection.options & V3270_SELECTION_NON_BREAKABLE_SPACE) != 0);
473 484 gtk_toggle_button_set_active(widget->input.checkboxes[1],(terminal->selection.options & V3270_SELECTION_SCREEN_PASTE) != 0);
474 485 gtk_toggle_button_set_active(widget->input.checkboxes[2],(terminal->selection.options & V3270_SELECTION_SMART_COPY) != 0);
  486 + gtk_toggle_button_set_active(widget->input.checkboxes[3],(terminal->selection.options & V3270_SELECTION_PIXBUFF) != 0);
475 487  
476 488 //
477 489 // Set font combo-box
... ... @@ -559,6 +571,12 @@ static void apply(GtkWidget *w, GtkWidget *t) {
559 571 terminal->selection.options &= ~V3270_SELECTION_SMART_COPY;
560 572 }
561 573  
  574 + if(gtk_toggle_button_get_active(widget->input.checkboxes[3])) {
  575 + terminal->selection.options |= V3270_SELECTION_PIXBUFF;
  576 + } else {
  577 + terminal->selection.options &= ~V3270_SELECTION_PIXBUFF;
  578 + }
  579 +
562 580 // Get font settings
563 581 switch(get_active_id(widget,0)) {
564 582 case '0':
... ...
src/dialogs/settings/host.c
... ... @@ -52,21 +52,21 @@
52 52 {
53 53 {
54 54 .left = 2,
55   - .top = 3,
56   - .width = 1,
  55 + .top = 2,
  56 + .width = 2,
57 57 .grid = CONNECTION,
58 58 .id = LIB3270_TOGGLE_CONNECT_ON_STARTUP,
59 59 },
60 60 {
61   - .left = 3,
62   - .top = 3,
  61 + .left = 4,
  62 + .top = 2,
63 63 .width = 1,
64 64 .grid = CONNECTION,
65 65 .id = LIB3270_TOGGLE_RECONNECT,
66 66 },
67 67 {
68   - .left = 4,
69   - .top = 3,
  68 + .left = 5,
  69 + .top = 2,
70 70 .width = 1,
71 71 .grid = CONNECTION,
72 72 .id = LIB3270_TOGGLE_KEEP_ALIVE,
... ... @@ -208,7 +208,7 @@
208 208 {
209 209 .left = 0,
210 210 .top = 0,
211   - .width = 4,
  211 + .width = 5,
212 212 .height = 1,
213 213 .grid = CONNECTION,
214 214  
... ... @@ -260,7 +260,7 @@
260 260 {
261 261 .left = 2,
262 262 .top = 1,
263   - .width = 2,
  263 + .width = 3,
264 264 .height = 1,
265 265 .grid = CONNECTION,
266 266  
... ... @@ -279,7 +279,7 @@
279 279 struct
280 280 {
281 281 GtkEntry * entry[G_N_ELEMENTS(entryfields)]; ///< @brief Entry fields for host & service name.
282   - GtkToggleButton * ssl; ///< @brief SSL Connection?
  282 + GtkComboBox * ssl; ///< @brief SSL Connection?
283 283 GtkComboBox * combos[G_N_ELEMENTS(combos)]; ///< @brief Combo-boxes.
284 284 GtkComboBox * charset; ///< @brief Charset combo box.
285 285 GtkToggleButton * toggles[G_N_ELEMENTS(toggleList)]; ///< @brief Toggle checks.
... ... @@ -540,12 +540,41 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget)
540 540  
541 541 }
542 542  
543   - // SSL checkbox
  543 + // SSL input
544 544 {
  545 + GtkWidget *label = gtk_label_new_with_mnemonic(_( "_Security" ));
  546 + gtk_widget_set_halign(label,GTK_ALIGN_END);
  547 + gtk_grid_attach(GTK_GRID(grids[CONNECTION]),label,0,3,1,1);
  548 +
  549 + GtkTreeModel * model = (GtkTreeModel *) gtk_list_store_new(1,G_TYPE_STRING);
  550 +
  551 + widget->input.ssl = GTK_COMBO_BOX(gtk_combo_box_new_with_model(model));
  552 +
  553 + GtkCellRenderer * text_renderer = gtk_cell_renderer_text_new();
  554 + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget->input.ssl), text_renderer, TRUE);
  555 + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(widget->input.ssl), text_renderer, "text", 0, NULL);
  556 +
  557 + static const gchar * levels[] =
  558 + {
  559 + N_("Unsecure"),
  560 + N_("SSL/TLS")
  561 + };
  562 +
  563 + size_t level;
  564 + for(level = 0; level < G_N_ELEMENTS(levels); level++)
  565 + {
  566 + GtkTreeIter iter;
  567 + gtk_list_store_append((GtkListStore *) model, &iter);
  568 + gtk_list_store_set((GtkListStore *) model, &iter, 0, levels[level], -1);
  569 + };
  570 +
  571 + /*
545 572 widget->input.ssl = GTK_TOGGLE_BUTTON(gtk_check_button_new_with_mnemonic(_( "_Secure connection." )));
546 573 gtk_widget_set_tooltip_text(GTK_WIDGET(widget->input.ssl),_( "Check for SSL secure connection." ));
547 574 gtk_widget_set_halign(GTK_WIDGET(widget->input.ssl),GTK_ALIGN_START);
548   - gtk_grid_attach(GTK_GRID(grids[CONNECTION]),GTK_WIDGET(widget->input.ssl),1,3,1,1);
  575 + */
  576 +
  577 + gtk_grid_attach(GTK_GRID(grids[CONNECTION]),GTK_WIDGET(widget->input.ssl),1,3,2,1);
549 578 }
550 579  
551 580 // Toggle checkboxes
... ... @@ -699,7 +728,7 @@ static void apply(GtkWidget *w, GtkWidget *terminal)
699 728 {
700 729 g_autofree gchar * url =
701 730 g_strconcat(
702   - (gtk_toggle_button_get_active(widget->input.ssl) ? "tn3270s://" : "tn3270://"),
  731 + (gtk_combo_box_get_active(widget->input.ssl) > 0 ? "tn3270s://" : "tn3270://"),
703 732 gtk_entry_get_text(widget->input.entry[ENTRY_HOSTNAME]),
704 733 ":",
705 734 gtk_entry_get_text(widget->input.entry[ENTRY_SRVCNAME]),
... ... @@ -778,9 +807,9 @@ static void load(GtkWidget *w, GtkWidget *terminal)
778 807 {
779 808  
780 809 g_autofree gchar * url = g_strdup(u);
781   - debug("URL=[%s]",url);
782 810  
783   - gtk_toggle_button_set_active(widget->input.ssl,g_str_has_prefix(u,"tn3270s"));
  811 + gtk_combo_box_set_active(widget->input.ssl,(g_str_has_prefix(u,"tn3270s") ? 1 : 0));
  812 +// gtk_toggle_button_set_active(widget->input.ssl,g_str_has_prefix(u,"tn3270s"));
784 813  
785 814 gchar *hostname = strstr(url,"://");
786 815 if(!hostname)
... ...
src/include/clipboard.h
... ... @@ -45,7 +45,8 @@
45 45 CLIPBOARD_TYPE_TEXT,
46 46 CLIPBOARD_TYPE_CSV,
47 47 CLIPBOARD_TYPE_HTML,
48   - CLIPBOARD_TYPE_V3270_FORMATTED
  48 + CLIPBOARD_TYPE_V3270_FORMATTED,
  49 + CLIPBOARD_TYPE_PIXBUFF
49 50 };
50 51  
51 52 /// @brief Column from selection.
... ... @@ -91,6 +92,7 @@
91 92  
92 93 /// @brief Get contents.
93 94 G_GNUC_INTERNAL gchar * v3270_get_selection_as_text(v3270 * terminal, const GList *selection, const gchar *encoding, gboolean all);
  95 + G_GNUC_INTERNAL GdkPixbuf * v3270_get_selection_as_pixbuf(v3270 * terminal, const GList *selection, gboolean all);
94 96 G_GNUC_INTERNAL gchar * v3270_get_selection_as_table(v3270 * terminal, const GList *selection, const gchar *delimiter, const gchar *encoding, gboolean all);
95 97 G_GNUC_INTERNAL gchar * v3270_get_selection_as_html_div(v3270 * terminal, const GList *selection, const gchar *encoding, gboolean all, const V3270SelectionOption options);
96 98 G_GNUC_INTERNAL gchar * v3270_get_selection_as_html_table(v3270 * terminal, const GList *selection, const gchar *encoding, gboolean all, const V3270SelectionOption options);
... ...
src/include/internals.h
... ... @@ -44,6 +44,7 @@
44 44 #include <lib3270/log.h>
45 45 #include <v3270.h>
46 46 #include <v3270/toggle.h>
  47 + #include <lib3270/popup.h>
47 48  
48 49 G_BEGIN_DECLS
49 50  
... ... @@ -82,7 +83,6 @@
82 83 V3270_SIGNAL_KEYPRESS,
83 84 V3270_SIGNAL_MODEL_CHANGED,
84 85 V3270_SIGNAL_CHANGED,
85   - V3270_SIGNAL_MESSAGE,
86 86 V3270_SIGNAL_FIELD,
87 87 V3270_SIGNAL_SESSION_CHANGED,
88 88  
... ... @@ -114,7 +114,9 @@
114 114 //
115 115 // Settings signals (Mostly fired by V3270Settings dialogs).
116 116 //
117   - V3270_SIGNAL_SAVE_SETTINGS, ///< @brief Notify main application to save all widget settings.
  117 + V3270_SIGNAL_SAVE_SETTINGS, ///< @brief Notify main application to save all widget settings.
  118 + V3270_SIGNAL_LOAD_POPUP_RESPONSE, ///< @brief Load popup response (GTK_RESPONSE_NONE to show popup).
  119 + V3270_SIGNAL_SAVE_POPUP_RESPONSE, ///< @brief Save popup response.
118 120  
119 121 V3270_SIGNAL_LAST
120 122 };
... ... @@ -133,6 +135,8 @@
133 135 G_GNUC_INTERNAL GtkWidget * v3270_dialog_create_grid(GtkAlign align);
134 136 G_GNUC_INTERNAL GtkWidget * v3270_dialog_create_frame(GtkWidget * child, const gchar *title);
135 137  
  138 + G_GNUC_INTERNAL GtkResponseType v3270_popup_dialog_show(GtkWidget *widget, const LIB3270_POPUP *popup, gboolean wait);
  139 +
136 140 G_GNUC_INTERNAL void v3270_signal_emit(gpointer instance, enum V3270_SIGNAL signal_id, ...);
137 141  
138 142 G_GNUC_INTERNAL void v3270_dialog_close(GtkDialog *dialog, gpointer user_data);
... ... @@ -181,6 +185,7 @@
181 185 unsigned short keycode;
182 186 } V3270PFKeyAccelerator;
183 187  
  188 + /*
184 189 typedef enum v3270_toggleable_dialog
185 190 {
186 191 V3270_TOGGLEABLE_DIALOG_PASTE_FAILED,
... ... @@ -189,6 +194,7 @@
189 194 } V3270_TOGGLEABLE_DIALOG;
190 195  
191 196 G_GNUC_INTERNAL GtkResponseType v3270_popup_toggleable_dialog(GtkWidget *widget, V3270_TOGGLEABLE_DIALOG id, const gchar *title, const gchar *summary, const gchar *body, const gchar *first_button_text, ...) G_GNUC_NULL_TERMINATED;
  197 + */
192 198  
193 199 #if GTK_CHECK_VERSION(3,12,0)
194 200 G_GNUC_INTERNAL GtkHeaderBar * v3270_dialog_get_header_bar(GtkWidget * widget);
... ...
src/include/terminal.h
... ... @@ -33,6 +33,7 @@
33 33  
34 34 G_BEGIN_DECLS
35 35  
  36 +/*
36 37 /// @brief V3270 Properties saved to the configuration file.
37 38 typedef enum
38 39 {
... ... @@ -56,6 +57,7 @@ G_BEGIN_DECLS
56 57 } V3270_SETTING;
57 58  
58 59 G_GNUC_INTERNAL void v3270_notify_setting(GtkWidget *widget, V3270_SETTING id);
  60 +*/
59 61  
60 62 struct _v3270Class
61 63 {
... ... @@ -69,7 +71,7 @@ G_BEGIN_DECLS
69 71 GParamSpec * toggle[LIB3270_TOGGLE_COUNT]; // Toggle properties.
70 72  
71 73 // Properties saved to the configuration file.
72   - GParamSpec * settings[V3270_SETTING_COUNT];
  74 + const gchar **persistent;
73 75  
74 76 // Signal related properties
75 77 GParamSpec * online;
... ... @@ -78,6 +80,7 @@ G_BEGIN_DECLS
78 80 GParamSpec * session_name;
79 81 GParamSpec * trace;
80 82 GParamSpec * has_copy;
  83 + GParamSpec * has_timer;
81 84  
82 85 struct
83 86 {
... ... @@ -86,14 +89,11 @@ G_BEGIN_DECLS
86 89 guint integer;
87 90 guint uint;
88 91 guint str;
89   - guint responses;
  92 +// guint responses;
90 93 } type;
91 94  
92 95 } properties;
93 96  
94   - // Predefined responses.
95   - GParamSpec * responses[V3270_TOGGLEABLE_DIALOG_CUSTOM];
96   -
97 97 // Cursors
98 98 GdkCursor * cursors[LIB3270_POINTER_COUNT];
99 99  
... ... @@ -104,7 +104,8 @@ G_BEGIN_DECLS
104 104 void (*activate)(GtkWidget *widget);
105 105 void (*toggle_changed)(v3270 *widget,LIB3270_TOGGLE_ID toggle_id,gboolean toggle_state,const gchar *toggle_name);
106 106 void (*message_changed)(v3270 *widget, LIB3270_MESSAGE id);
107   - void (*popup_message)(GtkWidget *widget, LIB3270_NOTIFY id , const gchar *title, const gchar *message, const gchar *text);
  107 + guint (*load_popup_response)(v3270 *widget, const gchar *popup_name, guint response);
  108 + gboolean (*save_popup_response)(v3270 *widget, const gchar *popup_name, guint response);
108 109  
109 110 };
110 111  
... ... @@ -127,6 +128,7 @@ G_BEGIN_DECLS
127 128 V3270_SELECTION_SCREEN_PASTE = 0x08, ///< @brief Enable screen paste.
128 129 V3270_SELECTION_SMART_COPY = 0x10, ///< @brief Enable copy/append based on current selection state.
129 130 V3270_SELECTION_DIALOG_STATE = 0x20, ///< @brief Used for settings dialog.
  131 + V3270_SELECTION_PIXBUFF = 0x40, ///< @brief Allow pixbuf formats.
130 132  
131 133 } V3270SelectionOption;
132 134  
... ... @@ -160,7 +162,7 @@ G_BEGIN_DECLS
160 162 int copying : 1; /// @brief Copy with center mouse button
161 163  
162 164 /// @brief Action properties.
163   - GtkResponseType responses[V3270_TOGGLEABLE_DIALOG_CUSTOM];
  165 +// GtkResponseType responses[V3270_TOGGLEABLE_DIALOG_CUSTOM];
164 166  
165 167 GSource * timer;
166 168 GtkIMContext * input_method;
... ... @@ -256,6 +258,7 @@ G_BEGIN_DECLS
256 258 };
257 259  
258 260 G_GNUC_INTERNAL void v3270_activate(GtkWidget *widget);
  261 + G_GNUC_INTERNAL GdkPixbuf * v3270_get_as_pixbuf(GtkWidget *widget);
259 262  
260 263 /*--[ Globals ]--------------------------------------------------------------------------------------*/
261 264  
... ...
src/include/v3270.h
... ... @@ -215,13 +215,10 @@
215 215 LIB3270_EXPORT GtkIMContext * v3270_get_im_context(GtkWidget *widget);
216 216 LIB3270_EXPORT const gchar * v3270_get_default_font_name();
217 217  
218   - LIB3270_EXPORT void v3270_popup_message(GtkWidget *widget, LIB3270_NOTIFY type, const gchar *title, const gchar *message, const gchar *text);
219   -
220 218 LIB3270_EXPORT const gchar * v3270_get_session_name(GtkWidget *widget);
221 219 LIB3270_EXPORT void v3270_set_session_name(GtkWidget *widget, const gchar *name);
222 220 LIB3270_EXPORT gchar * v3270_get_session_title(GtkWidget *widget);
223 221  
224   -// LIB3270_EXPORT gchar * v3270_get_title(GtkWidget *widget);
225 222 LIB3270_EXPORT gchar * v3270_set_title(GtkWidget *widget, const gchar *title);
226 223  
227 224 LIB3270_EXPORT int v3270_set_script(GtkWidget *widget, const gchar id);
... ...
src/include/v3270/settings.h
... ... @@ -48,7 +48,7 @@
48 48 LIB3270_EXPORT void v3270_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name);
49 49  
50 50 /// @brief Emit the "save-settings" signal.
51   - LIB3270_EXPORT void v3270_emit_save_settings(GtkWidget *widget);
  51 + LIB3270_EXPORT void v3270_emit_save_settings(GtkWidget *widget, const gchar *property_name);
52 52  
53 53 #ifdef _WIN32
54 54  
... ...
src/selection/linux/copy.c
... ... @@ -104,6 +104,20 @@ static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionDa
104 104 }
105 105 break;
106 106  
  107 + case CLIPBOARD_TYPE_PIXBUFF:
  108 + {
  109 + GdkPixbuf * pixbuff = v3270_get_selection_as_pixbuf(terminal, terminal->selection.blocks, FALSE);
  110 +
  111 + debug("%s: pixbuff=%p (blocks=%p)",__FUNCTION__,pixbuff,terminal->selection.blocks);
  112 +
  113 + if(pixbuff)
  114 + {
  115 + gtk_selection_data_set_pixbuf(selection,pixbuff);
  116 + g_object_unref(pixbuff);
  117 + }
  118 + }
  119 + break;
  120 +
107 121 default:
108 122 g_warning("Unexpected clipboard type %d\n",target);
109 123 }
... ... @@ -143,6 +157,11 @@ void v3270_update_system_clipboard(GtkWidget *widget)
143 157  
144 158 }
145 159  
  160 + if(terminal->selection.options & V3270_SELECTION_PIXBUFF)
  161 + {
  162 + gtk_target_list_add_image_targets(list,CLIPBOARD_TYPE_PIXBUFF,TRUE);
  163 + }
  164 +
146 165 int n_targets;
147 166 GtkTargetEntry * targets = gtk_target_table_new_from_list(list, &n_targets);
148 167  
... ...
src/selection/linux/paste.c
... ... @@ -30,6 +30,7 @@
30 30 #include <clipboard.h>
31 31 #include <lib3270/toggle.h>
32 32 #include <v3270/dialogs.h>
  33 + #include <lib3270/popup.h>
33 34  
34 35 /*--[ Implement ]------------------------------------------------------------------------------------*/
35 36  
... ... @@ -108,17 +109,16 @@ static void formatted_received(GtkClipboard *clipboard, GtkSelectionData *select
108 109 if(!v3270_set_from_data_block(terminal, selection))
109 110 {
110 111 debug("%s: Can't paste data",__FUNCTION__);
111   - if(
112   - v3270_popup_toggleable_dialog(
113   - widget,
114   - V3270_TOGGLEABLE_DIALOG_PASTE_FAILED,
115   - _("Can't paste"),
116   - _("Unable to paste formatted data."),
117   - _("None of the screens in the clipboard match with the current one."),
118   - _("_Cancel"), GTK_RESPONSE_CANCEL,
119   - _("_Paste as text"), GTK_RESPONSE_APPLY,
120   - NULL
121   - ) == GTK_RESPONSE_APPLY)
  112 +
  113 + LIB3270_POPUP popup = {
  114 + .name = "cantpaste",
  115 + .title = _("Can't paste"),
  116 + .summary = _("Unable to paste formatted data."),
  117 + .body = _("None of the screens in the clipboard match with the current one."),
  118 + .label = _("_Paste as text")
  119 + };
  120 +
  121 + if(v3270_popup_dialog_show(widget,&popup,1) == GTK_RESPONSE_APPLY)
122 122 {
123 123 gtk_clipboard_request_text(
124 124 clipboard,
... ... @@ -127,51 +127,8 @@ static void formatted_received(GtkClipboard *clipboard, GtkSelectionData *select
127 127 );
128 128 }
129 129  
130   - /*
131   - GtkResponseType response = GTK_V3270(terminal)->responses[V3270_TOGGLEABLE_DIALOG_PASTE_FAILED];
132   -
133   - if(response == GTK_RESPONSE_NONE)
134   - {
135   - // No predefined response, ask.
136   - GtkWidget * dialog =
137   - gtk_message_dialog_new(
138   - GTK_WINDOW(gtk_widget_get_toplevel(widget)),
139   - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
140   - GTK_MESSAGE_INFO,
141   - GTK_BUTTONS_NONE,
142   - _("Unable to paste formatted data")
143   - );
144   -
145   -
146   - gtk_window_set_title(GTK_WINDOW(dialog),_("Can't paste"));
147   -
148   - gtk_dialog_add_buttons(
149   - GTK_DIALOG (dialog),
150   - _("_Cancel"), GTK_RESPONSE_CANCEL,
151   - _("_Paste as text"), GTK_RESPONSE_APPLY,
152   - NULL
153   - );
154   -
155   - gtk_dialog_set_default_response(GTK_DIALOG (dialog),response);
156   -
157   - gint response = gtk_dialog_run(GTK_DIALOG(dialog));
158   -
159   - gtk_widget_destroy(dialog);
160   - }
161   -
162   - if(response == GTK_RESPONSE_APPLY)
163   - {
164   - gtk_clipboard_request_text(
165   - clipboard,
166   - (GtkClipboardTextReceivedFunc) text_received,
167   - (gpointer) widget
168   - );
169   - }
170   -
171   - */
172 130 return;
173 131  
174   -
175 132 }
176 133  
177 134 }
... ...
src/selection/pixbuf.c 0 → 100644
... ... @@ -0,0 +1,153 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 + #include <clipboard.h>
  31 + #include <lib3270/selection.h>
  32 + #include <v3270/dialogs.h>
  33 +
  34 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  35 +
  36 +GdkPixbuf * v3270_get_selection_as_pixbuf(v3270 * terminal, const GList *selections, gboolean all)
  37 +{
  38 + const GList *selection;
  39 +
  40 + // Get image size
  41 + size_t rows = 0, from_col = 1000, to_col = 0;
  42 +
  43 + for(selection = selections; selection; selection = g_list_next(selection))
  44 + {
  45 + lib3270_selection * block = ((lib3270_selection *) selection->data);
  46 + unsigned int row, src = 0;
  47 +
  48 + for(row=0; row < block->bounds.height; row++)
  49 + {
  50 + size_t hasSelection = FALSE;
  51 + unsigned int col;
  52 +
  53 + for(col=0; col<block->bounds.width; col++)
  54 + {
  55 + if( (block->contents[src].attribute.visual & LIB3270_ATTR_SELECTED) || all )
  56 + {
  57 + hasSelection = TRUE;
  58 + if(col < from_col)
  59 + from_col = col;
  60 + if(col > to_col)
  61 + to_col = col;
  62 + }
  63 + src++;
  64 + }
  65 +
  66 + if(hasSelection)
  67 + {
  68 + rows++;
  69 + }
  70 +
  71 + }
  72 +
  73 + }
  74 +
  75 + debug("Selection rows=%u cols=%u",(unsigned int) rows, (unsigned int) (to_col - from_col));
  76 +
  77 + if(!(rows || (from_col > to_col)))
  78 + return NULL;
  79 +
  80 + gint width = ((to_col - from_col)+1) * terminal->font.width;
  81 + gint height = rows * terminal->font.spacing.value;
  82 +
  83 + debug("%s: width=%d height=%d",__FUNCTION__,width,height);
  84 +
  85 + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  86 +
  87 + cairo_t *cr = cairo_create(surface);
  88 +#ifdef DEBUG
  89 + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_BLUE);
  90 +#else
  91 + gdk_cairo_set_source_rgba(cr,terminal->color+V3270_COLOR_BACKGROUND);
  92 +#endif // DEBUG
  93 + cairo_rectangle(cr, 0, 0, width, height);
  94 + cairo_fill(cr);
  95 + cairo_stroke(cr);
  96 +
  97 + // Draw contents
  98 + GdkRectangle rect;
  99 + memset(&rect,0,sizeof(rect));
  100 + rect.width = terminal->font.width;
  101 + rect.height = terminal->font.spacing.value;
  102 +
  103 + cairo_set_scaled_font(cr,terminal->font.scaled);
  104 +
  105 + for(selection = selections; selection; selection = g_list_next(selection))
  106 + {
  107 + lib3270_selection * block = ((lib3270_selection *) selection->data);
  108 + unsigned int row, col, src = 0;
  109 +
  110 + for(row=0; row < block->bounds.height; row++)
  111 + {
  112 + size_t hasSelection = FALSE;
  113 + rect.x = 0;
  114 +
  115 + src += from_col;
  116 + for(col=from_col; col<block->bounds.width; col++)
  117 + {
  118 + if( (block->contents[src].attribute.visual & LIB3270_ATTR_SELECTED) || all )
  119 + {
  120 + hasSelection = TRUE;
  121 +
  122 + v3270_draw_element(
  123 + cr,
  124 + block->contents[src].chr,
  125 + block->contents[src].attribute.visual & ~LIB3270_ATTR_SELECTED,
  126 + terminal->host,
  127 + &terminal->font,
  128 + &rect,
  129 + terminal->color
  130 + );
  131 +
  132 + }
  133 + src++;
  134 + rect.x += rect.width;
  135 + }
  136 +
  137 + if(hasSelection)
  138 + {
  139 + rect.y += terminal->font.spacing.value;
  140 + }
  141 +
  142 + }
  143 + }
  144 +
  145 + cairo_destroy(cr);
  146 +
  147 + GdkPixbuf * pixbuf = gdk_pixbuf_get_from_surface(surface,0,0,width,height);
  148 +
  149 + cairo_surface_destroy(surface);
  150 +
  151 + return pixbuf;
  152 +
  153 +}
... ...
src/selection/selection.c
... ... @@ -151,7 +151,7 @@ void v3270_selection_set_font_family(GtkWidget *widget, const gchar *name) {
151 151 terminal->selection.font_family = g_strdup(name);
152 152 }
153 153  
154   - v3270_emit_save_settings(widget);
  154 + v3270_emit_save_settings(widget,NULL);
155 155  
156 156 }
157 157  
... ... @@ -181,7 +181,7 @@ void v3270_selection_set_color_scheme(GtkWidget *widget, const gchar *name) {
181 181 terminal->selection.color.scheme = g_strdup(name);
182 182 }
183 183  
184   - v3270_emit_save_settings(widget);
  184 + v3270_emit_save_settings(widget,NULL);
185 185  
186 186 }
187 187  
... ...
src/selection/windows/copy.c
... ... @@ -104,6 +104,20 @@ static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionDa
104 104 }
105 105 break;
106 106  
  107 + case CLIPBOARD_TYPE_PIXBUFF:
  108 + {
  109 + GdkPixbuf * pixbuff = v3270_get_selection_as_pixbuf(terminal, terminal->selection.blocks, FALSE);
  110 +
  111 + debug("%s: pixbuff=%p (blocks=%p)",__FUNCTION__,pixbuff,terminal->selection.blocks);
  112 +
  113 + if(pixbuff)
  114 + {
  115 + gtk_selection_data_set_pixbuf(selection,pixbuff);
  116 + g_object_unref(pixbuff);
  117 + }
  118 + }
  119 + break;
  120 +
107 121 default:
108 122 g_warning("Unexpected clipboard type %d\n",target);
109 123 }
... ... @@ -143,6 +157,11 @@ void v3270_update_system_clipboard(GtkWidget *widget)
143 157  
144 158 }
145 159  
  160 + if(terminal->selection.options & V3270_SELECTION_PIXBUFF)
  161 + {
  162 + gtk_target_list_add_image_targets(list,CLIPBOARD_TYPE_PIXBUFF,TRUE);
  163 + }
  164 +
146 165 int n_targets;
147 166 GtkTargetEntry * targets = gtk_target_table_new_from_list(list, &n_targets);
148 167  
... ...
src/terminal/actions/action.c
... ... @@ -246,7 +246,7 @@
246 246 }
247 247  
248 248 static gboolean bg_notify_enabled(GObject *action) {
249   - debug("%s(%s,%s,%d)",__FUNCTION__,g_action_get_name(G_ACTION(action)),(g_action_get_enabled(G_ACTION(action)) ? "enabled" : "disabled"),(int) v3270_action_get_group(G_ACTION(action)));
  249 +// debug("%s(%s,%s,%d)",__FUNCTION__,g_action_get_name(G_ACTION(action)),(g_action_get_enabled(G_ACTION(action)) ? "enabled" : "disabled"),(int) v3270_action_get_group(G_ACTION(action)));
250 250 g_object_notify(action, "enabled");
251 251 return FALSE;
252 252 }
... ...
src/terminal/actions/table.c
... ... @@ -56,7 +56,7 @@
56 56  
57 57 // Standard Clipboard actions
58 58 {
59   - .flags = V3270_COPY_SMART,
  59 + .flags = (V3270_ACTION_FLAGS) V3270_COPY_SMART,
60 60 .name = "copy",
61 61 .keys = "<Primary>c",
62 62 .group = LIB3270_ACTION_GROUP_SELECTION,
... ... @@ -70,7 +70,7 @@
70 70 {
71 71 .name = "copy-append",
72 72 .keys = "<Alt>c",
73   - .flags = V3270_COPY_APPEND,
  73 + .flags = (V3270_ACTION_FLAGS) V3270_COPY_APPEND,
74 74 .group = LIB3270_ACTION_GROUP_SELECTION,
75 75 .label = N_( "Add to copy" ),
76 76 .summary = N_("Append selection to clipboard"),
... ... @@ -81,7 +81,7 @@
81 81 {
82 82 .name = "copy-text",
83 83 .keys = "<Primary><Shift>c",
84   - .flags = V3270_COPY_TEXT,
  84 + .flags = (V3270_ACTION_FLAGS) V3270_COPY_TEXT,
85 85 .group = LIB3270_ACTION_GROUP_SELECTION,
86 86 .icon = "edit-copy",
87 87 .label = N_( "Copy" ),
... ... @@ -92,7 +92,7 @@
92 92 {
93 93 .name = "copy-table",
94 94 .keys = "<Shift><Alt>c",
95   - .flags = V3270_COPY_TABLE,
  95 + .flags = (V3270_ACTION_FLAGS) V3270_COPY_TABLE,
96 96 .group = LIB3270_ACTION_GROUP_SELECTION,
97 97 .icon = "edit-copy",
98 98 .label = N_( "Copy as table" ),
... ... @@ -234,7 +234,7 @@
234 234 },
235 235  
236 236 {
237   - .flags = LIB3270_CONTENT_ALL,
  237 + .flags = (V3270_ACTION_FLAGS) LIB3270_CONTENT_ALL,
238 238 .group = LIB3270_ACTION_GROUP_ONLINE,
239 239 .name = "save-all",
240 240 .label = N_("Save all"),
... ... @@ -245,7 +245,7 @@
245 245 },
246 246  
247 247 {
248   - .flags = LIB3270_CONTENT_SELECTED,
  248 + .flags = (V3270_ACTION_FLAGS) LIB3270_CONTENT_SELECTED,
249 249 .group = LIB3270_ACTION_GROUP_SELECTION,
250 250 .name = "save-selected",
251 251 .label = N_("Save selected"),
... ... @@ -256,7 +256,7 @@
256 256 },
257 257  
258 258 {
259   - .flags = LIB3270_CONTENT_COPY,
  259 + .flags = (V3270_ACTION_FLAGS) LIB3270_CONTENT_COPY,
260 260 .group = LIB3270_ACTION_GROUP_COPY,
261 261 .name = "save-copy",
262 262 .label = N_("Save copy"),
... ... @@ -281,7 +281,7 @@
281 281 },
282 282  
283 283 {
284   - .flags = LIB3270_CONTENT_ALL,
  284 + .flags = (V3270_ACTION_FLAGS) LIB3270_CONTENT_ALL,
285 285 .group = LIB3270_ACTION_GROUP_ONLINE,
286 286 .name = "print-all",
287 287 .icon = "document-print",
... ... @@ -292,7 +292,7 @@
292 292 },
293 293  
294 294 {
295   - .flags = LIB3270_CONTENT_SELECTED,
  295 + .flags = (V3270_ACTION_FLAGS) LIB3270_CONTENT_SELECTED,
296 296 .group = LIB3270_ACTION_GROUP_SELECTION,
297 297 .name = "print-selected",
298 298 .icon = "document-print",
... ... @@ -303,7 +303,7 @@
303 303 },
304 304  
305 305 {
306   - .flags = LIB3270_CONTENT_COPY,
  306 + .flags = (V3270_ACTION_FLAGS) LIB3270_CONTENT_COPY,
307 307 .group = LIB3270_ACTION_GROUP_COPY,
308 308 .name = "print-copy",
309 309 .icon = "document-print",
... ...
src/terminal/actions/toggle.c
... ... @@ -112,7 +112,7 @@
112 112 return G_VARIANT_TYPE_BOOLEAN;
113 113 }
114 114  
115   - static gboolean get_enabled(GAction *action, GtkWidget *terminal) {
  115 + static gboolean get_enabled(GAction G_GNUC_UNUSED(*action), GtkWidget G_GNUC_UNUSED(*terminal)) {
116 116 return TRUE;
117 117 }
118 118  
... ... @@ -126,7 +126,7 @@
126 126  
127 127 }
128 128  
129   - void Lib3270ToggleAction_init(Lib3270ToggleAction *action) {
  129 + void Lib3270ToggleAction_init(Lib3270ToggleAction G_GNUC_UNUSED(*action)) {
130 130 }
131 131  
132 132 GAction * g_action_new_from_toggle(const LIB3270_TOGGLE * definition) {
... ...
src/terminal/callbacks.c
... ... @@ -43,19 +43,41 @@
43 43 #include <lib3270.h>
44 44 #include <lib3270/session.h>
45 45 #include <lib3270/log.h>
  46 + #include <lib3270/popup.h>
46 47 #include <errno.h>
  48 + #include <v3270/settings.h>
47 49  
48 50 /*--[ Implement ]------------------------------------------------------------------------------------*/
49 51  
50   -static void set_timer(H3270 *session, unsigned char on)
  52 +struct has_timer
51 53 {
52   - GtkWidget *widget = GTK_WIDGET(lib3270_get_user_data(session));
  54 + H3270 * hSession;
  55 + unsigned char on;
  56 +};
  57 +
  58 +static gboolean bg_has_timer(struct has_timer *data)
  59 +{
  60 + GtkWidget *widget = GTK_WIDGET(lib3270_get_user_data(data->hSession));
53 61  
54   - if(on)
  62 + if(data->on)
55 63 v3270_start_timer(widget);
56 64 else
57 65 v3270_stop_timer(widget);
58 66  
  67 + g_free(data);
  68 +
  69 + return FALSE;
  70 +}
  71 +
  72 +static void set_timer(H3270 *session, unsigned char on)
  73 +{
  74 + struct has_timer *data = g_malloc0(sizeof(struct has_timer));
  75 +
  76 + data->hSession = session;
  77 + data->on = on;
  78 +
  79 + g_idle_add((GSourceFunc) bg_has_timer, data);
  80 +
59 81 }
60 82  
61 83 static void update_toggle(H3270 *session, LIB3270_TOGGLE_ID id, unsigned char value, G_GNUC_UNUSED LIB3270_TOGGLE_TYPE reason, const char *name)
... ... @@ -91,7 +113,8 @@ static gboolean v3270_update_url(v3270 *terminal)
91 113 {
92 114 GtkWidget * widget = GTK_WIDGET(terminal);
93 115 debug("url=%s",v3270_get_url(widget));
94   - v3270_notify_setting(widget,V3270_SETTING_URL);
  116 +
  117 + v3270_emit_save_settings(widget,"url");
95 118 v3270_signal_emit(widget, V3270_SIGNAL_SESSION_CHANGED);
96 119 return FALSE;
97 120 }
... ... @@ -180,9 +203,7 @@ static void update_model(H3270 *session, const char *name, int model, G_GNUC_UNU
180 203 {
181 204 GtkWidget * widget = GTK_WIDGET(lib3270_get_user_data(session));
182 205  
183   - debug("%s: terminal=%p pspec=%p",__FUNCTION__,widget,GTK_V3270_GET_CLASS(widget)->properties.settings[V3270_SETTING_MODEL_NUMBER]);
184   - g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->properties.settings[V3270_SETTING_MODEL_NUMBER]);
185   -
  206 +// g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->properties.settings[V3270_SETTING_MODEL_NUMBER]);
186 207 v3270_signal_emit(widget,V3270_SIGNAL_MODEL_CHANGED, (guint) model, name);
187 208 }
188 209  
... ... @@ -255,18 +276,20 @@ static void update_selection(H3270 *session, G_GNUC_UNUSED int start, G_GNUC_UNU
255 276  
256 277 }
257 278  
258   -static void message(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *text)
  279 +/*
  280 +static void message(H3270 *session, LIB3270_NOTIFY type , const char *title, const char *message, const char *text)
259 281 {
260   - v3270_signal_emit(
261   - GTK_WIDGET(lib3270_get_user_data(session)),
262   - V3270_SIGNAL_MESSAGE,
263   - (int) id,
264   - (gchar *) title,
265   - (gchar *) message,
266   - (gchar *) text
267   - );
  282 + LIB3270_POPUP popup = {
  283 + .type = type,
  284 + .title = title,
  285 + .summary = message,
  286 + .body = text
  287 + };
  288 +
  289 + v3270_popup_dialog_show(GTK_WIDGET(lib3270_get_user_data(session)),&popup,0);
268 290  
269 291 }
  292 +*/
270 293  
271 294 static int print(H3270 *session, LIB3270_CONTENT_OPTION mode)
272 295 {
... ... @@ -303,27 +326,26 @@ static int load(H3270 *session, const char *filename)
303 326 return 0;
304 327 }
305 328  
  329 +/*
306 330 static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list args)
307 331 {
308   - GtkWidget *terminal = (GtkWidget *) lib3270_get_user_data(session);
  332 + LIB3270_POPUP popup = {
  333 + .type = type,
  334 + .title = title,
  335 + .summary = msg
  336 + };
309 337  
310   - if(terminal && GTK_IS_V3270(terminal))
311   - {
  338 + g_autofree gchar * body = NULL;
312 339  
313   - if(fmt)
314   - {
315   - gchar *text = g_strdup_vprintf(fmt,args);
316   - v3270_popup_message(GTK_WIDGET(terminal),type,title,msg,text);
317   - g_free(text);
318   - }
319   - else
320   - {
321   - v3270_popup_message(GTK_WIDGET(terminal),type,title,msg,NULL);
322   - }
  340 + if(fmt) {
  341 + body = g_strdup_vprintf(fmt,args);
  342 + popup.body = body;
  343 + }
323 344  
324   - }
  345 + v3270_popup_dialog_show(GTK_WIDGET(lib3270_get_user_data(session)),&popup,0);
325 346  
326 347 }
  348 + */
327 349  
328 350 static gboolean bg_update_ssl(H3270 *session)
329 351 {
... ... @@ -362,6 +384,7 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
362 384 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,(GSourceFunc) bg_update_oia, data, g_free);
363 385 }
364 386  
  387 + /*
365 388 static int popup_ssl_error(H3270 *session, int rc, const char *title, const char *summary, const char *body)
366 389 {
367 390 GtkWidget *terminal = (GtkWidget *) lib3270_get_user_data(session);
... ... @@ -411,17 +434,47 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
411 434  
412 435 return -1;
413 436 }
  437 + */
  438 +
  439 + static int popup(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait) {
  440 +
  441 + GtkResponseType response = v3270_popup_dialog_show(
  442 + GTK_WIDGET(lib3270_get_user_data(hSession)),
  443 + popup,
  444 + wait != 0);
  445 +
  446 + if(response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
  447 + return 0;
  448 +
  449 + return errno = ECANCELED;
  450 +
  451 + }
414 452  
415 453 void v3270_install_callbacks(v3270 *widget)
416 454 {
417 455 struct lib3270_session_callbacks *cbk;
418 456  
419   - lib3270_set_popup_handler(widget->host, popup_handler);
420   -
421   - cbk = lib3270_get_session_callbacks(widget->host,sizeof(struct lib3270_session_callbacks));
  457 + cbk = lib3270_get_session_callbacks(widget->host,G_STRINGIFY(LIB3270_REVISION),sizeof(struct lib3270_session_callbacks));
422 458 if(!cbk)
423 459 {
424   - g_error( _( "Invalid callback table, possible version mismatch in lib3270") );
  460 + if(g_ascii_strcasecmp(G_STRINGIFY(LIB3270_REVISION),lib3270_get_revision()))
  461 + {
  462 + g_error(
  463 + _("Invalid callback table, the release %s of lib%s can't be used (expecting revision %s)"),
  464 + lib3270_get_revision(),
  465 + G_STRINGIFY(LIB3270_NAME),
  466 + G_STRINGIFY(LIB3270_REVISION)
  467 + );
  468 + }
  469 + else
  470 + {
  471 + g_error(
  472 + _("Unexpected callback table, the release %s of lib%s is invalid"),
  473 + lib3270_get_revision(),
  474 + G_STRINGIFY(LIB3270_NAME)
  475 + );
  476 + }
  477 +
425 478 return;
426 479 }
427 480  
... ... @@ -445,12 +498,11 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
445 498 cbk->update_model = update_model;
446 499 cbk->changed = changed;
447 500 cbk->ctlr_done = ctlr_done;
448   - cbk->message = message;
449 501 cbk->update_ssl = update_ssl;
450 502 cbk->print = print;
451 503 cbk->save = save;
452 504 cbk->load = load;
453   - cbk->popup_ssl_error = popup_ssl_error;
  505 + cbk->popup = popup;
454 506  
455 507 }
456 508  
... ...
src/terminal/charset.c
... ... @@ -40,6 +40,7 @@
40 40 #include <lib3270/charset.h>
41 41 #include <lib3270/log.h>
42 42 #include <v3270/dialogs.h>
  43 + #include <v3270/settings.h>
43 44  
44 45 #define ERROR_DOMAIN g_quark_from_static_string(PACKAGE_NAME)
45 46  
... ... @@ -337,8 +338,7 @@
337 338 g_free(cfg.host);
338 339 g_free(cfg.display);
339 340  
340   - debug("%s=%p",__FUNCTION__,GTK_V3270_GET_CLASS(widget)->properties.settings[V3270_SETTING_REMAP_FILE]);
341   - v3270_notify_setting(widget,V3270_SETTING_REMAP_FILE);
  341 + v3270_emit_save_settings(widget,"remap_file");
342 342  
343 343 }
344 344  
... ...
src/terminal/colors.c
... ... @@ -36,40 +36,92 @@
36 36  
37 37 /*--[ Implement ]------------------------------------------------------------------------------------*/
38 38  
39   -const gchar * v3270_get_default_colors() {
40   -
41   - return "#000000," // V3270_COLOR_BACKGROUND
42   - "#7890F0," // V3270_COLOR_BLUE
43   - "#FF0000," // V3270_COLOR_RED
44   - "#FF00FF," // V3270_COLOR_PINK
45   - "#00FF00," // V3270_COLOR_GREEN
46   - "#00FFFF," // V3270_COLOR_TURQUOISE
47   - "#FFFF00," // V3270_COLOR_YELLOW
48   - "#FFFFFF," // V3270_COLOR_WHITE
49   - "#000000," // V3270_COLOR_BLACK
50   - "#000080," // V3270_COLOR_DARK_BLUE
51   - "#FFA200," // V3270_COLOR_ORANGE
52   - "#800080," // V3270_COLOR_PURPLE
53   - "#008000," // V3270_COLOR_DARK_GREEN
54   - "#008080," // V3270_COLOR_DARK_TURQUOISE
55   - "#A0A000," // V3270_COLOR_MUSTARD
56   - "#C0C0C0," // V3270_COLOR_GRAY
57   -
58   - "#00FF00," // V3270_COLOR_FIELD_DEFAULT
59   - "#FF0000," // V3270_COLOR_FIELD_INTENSIFIED
60   - "#00FFFF," // V3270_COLOR_FIELD_PROTECTED
61   - "#FFFFFF," // V3270_COLOR_FIELD_PROTECTED_INTENSIFIED
62   -
63   - "#404040," // V3270_COLOR_SELECTED_BG
64   - "#FFFFFF," // V3270_COLOR_SELECTED_FG,
65   -
66   - "#00FF00," // V3270_COLOR_CROSS_HAIR
67   -
68   - "#000000," // V3270_COLOR_OIA_BACKGROUND
69   - "#00FF00," // V3270_COLOR_OIA
70   - "#7890F0," // V3270_COLOR_OIA_SEPARATOR
71   - "#FFFFFF," // V3270_COLOR_OIA_STATUS_OK
72   - "#FFFF00," // V3270_COLOR_OIA_STATUS_WARNING
  39 +const gchar * v3270_get_default_colors()
  40 +{
  41 +
  42 +#ifdef _WIN32
  43 + {
  44 + HKEY hKey;
  45 + DWORD disp = 0;
  46 + LSTATUS rc = RegCreateKeyEx(
  47 + HKEY_LOCAL_MACHINE,
  48 + "Software\\" LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),
  49 + 0,
  50 + NULL,
  51 + REG_OPTION_NON_VOLATILE,
  52 + KEY_QUERY_VALUE|KEY_READ,
  53 + NULL,
  54 + &hKey,
  55 + &disp);
  56 +
  57 + debug("%s=%d","Software\\" LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),rc);
  58 +
  59 + if(rc == ERROR_SUCCESS)
  60 + {
  61 + static char * default_colors = NULL;
  62 + DWORD cbData = 4096;
  63 +
  64 + if(!default_colors)
  65 + {
  66 + default_colors = (char *) malloc(cbData+1);
  67 + }
  68 + else
  69 + {
  70 + default_colors = (char *) realloc(default_colors,cbData+1);
  71 + }
  72 +
  73 + DWORD dwRet = RegQueryValueEx(hKey,"colors",NULL,NULL,(LPBYTE) default_colors, &cbData);
  74 +
  75 + debug("dwRet=%d",dwRet);
  76 +
  77 + RegCloseKey(hKey);
  78 +
  79 + if(dwRet == ERROR_SUCCESS)
  80 + {
  81 + default_colors = (char *) realloc(default_colors,cbData+1);
  82 + default_colors[cbData] = 0;
  83 +
  84 + return default_colors;
  85 + }
  86 +
  87 + free(default_colors);
  88 + default_colors = NULL;
  89 + }
  90 + }
  91 +#endif // _WIN32
  92 +
  93 + return "#000000;" // V3270_COLOR_BACKGROUND
  94 + "#7890F0;" // V3270_COLOR_BLUE
  95 + "#FF0000;" // V3270_COLOR_RED
  96 + "#FF00FF;" // V3270_COLOR_PINK
  97 + "#00FF00;" // V3270_COLOR_GREEN
  98 + "#00FFFF;" // V3270_COLOR_TURQUOISE
  99 + "#FFFF00;" // V3270_COLOR_YELLOW
  100 + "#FFFFFF;" // V3270_COLOR_WHITE
  101 + "#000000;" // V3270_COLOR_BLACK
  102 + "#000080;" // V3270_COLOR_DARK_BLUE
  103 + "#FFA200;" // V3270_COLOR_ORANGE
  104 + "#800080;" // V3270_COLOR_PURPLE
  105 + "#008000;" // V3270_COLOR_DARK_GREEN
  106 + "#008080;" // V3270_COLOR_DARK_TURQUOISE
  107 + "#A0A000;" // V3270_COLOR_MUSTARD
  108 + "#C0C0C0;" // V3270_COLOR_GRAY
  109 +
  110 + "#00FF00;" // V3270_COLOR_FIELD_DEFAULT
  111 + "#FF0000;" // V3270_COLOR_FIELD_INTENSIFIED
  112 + "#00FFFF;" // V3270_COLOR_FIELD_PROTECTED
  113 + "#FFFFFF;" // V3270_COLOR_FIELD_PROTECTED_INTENSIFIED
  114 +
  115 + "#404040;" // V3270_COLOR_SELECTED_BG
  116 + "#FFFFFF;" // V3270_COLOR_SELECTED_FG,
  117 +
  118 + "#00FF00;" // V3270_COLOR_CROSS_HAIR
  119 +
  120 + "#000000;" // V3270_COLOR_OIA_BACKGROUND
  121 + "#00FF00;" // V3270_COLOR_OIA
  122 + "#7890F0;" // V3270_COLOR_OIA_SEPARATOR
  123 + "#FFFFFF;" // V3270_COLOR_OIA_STATUS_OK
  124 + "#FFFF00;" // V3270_COLOR_OIA_STATUS_WARNING
73 125 "#FFFF00"; // V3270_COLOR_OIA_STATUS_INVALID
74 126 }
75 127  
... ... @@ -83,7 +135,7 @@ LIB3270_EXPORT void v3270_set_colors(GtkWidget *widget, const gchar *colors)
83 135 }
84 136  
85 137 v3270_set_color_table(GTK_V3270(widget)->color,colors);
86   - v3270_emit_save_settings(widget);
  138 + v3270_emit_save_settings(widget,NULL);
87 139 v3270_reload(widget);
88 140  
89 141 }
... ...
src/terminal/drawing/draw.c
... ... @@ -524,6 +524,29 @@ LIB3270_EXPORT void v3270_reload(GtkWidget *widget)
524 524  
525 525 }
526 526  
  527 +GdkPixbuf * v3270_get_as_pixbuf(GtkWidget *widget)
  528 +{
  529 + v3270 * terminal = GTK_V3270(widget);
  530 +
  531 + if(!(gtk_widget_get_realized(widget) && terminal->drawing))
  532 + return NULL;
  533 +
  534 + gint width = gtk_widget_get_allocated_width(widget);
  535 + gint height = gtk_widget_get_allocated_height(widget);
  536 +
  537 + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  538 +
  539 + cairo_t *cr = cairo_create(surface);
  540 + v3270_redraw(terminal, cr, width, height);
  541 + cairo_destroy (cr);
  542 +
  543 + GdkPixbuf * pixbuf = gdk_pixbuf_get_from_surface(surface,0,0,width,height);
  544 +
  545 + cairo_surface_destroy (surface);
  546 +
  547 + return pixbuf;
  548 +}
  549 +
527 550 void v3270_update_char(H3270 *session, int addr, unsigned char chr, unsigned short attr, unsigned char cursor)
528 551 {
529 552 v3270 * terminal = GTK_V3270(lib3270_get_user_data(session));
... ...
src/terminal/drawing/oia.c
... ... @@ -827,6 +827,7 @@ struct timer_info
827 827 static void release_timer(struct timer_info *info)
828 828 {
829 829 info->terminal->timer = NULL;
  830 + g_object_notify_by_pspec(G_OBJECT(info->terminal),GTK_V3270_GET_CLASS(info->terminal)->properties.has_timer);
830 831  
831 832 if(info->terminal->surface)
832 833 {
... ... @@ -1051,6 +1052,8 @@ void v3270_start_timer(GtkWidget *widget)
1051 1052 terminal->timer = g_timeout_source_new(100);
1052 1053 g_source_set_callback(terminal->timer,(GSourceFunc) update_timer, info, (GDestroyNotify) release_timer);
1053 1054  
  1055 + g_object_notify_by_pspec(G_OBJECT(terminal),GTK_V3270_GET_CLASS(widget)->properties.has_timer);
  1056 +
1054 1057 g_source_attach(terminal->timer,NULL);
1055 1058 g_source_unref(terminal->timer);
1056 1059  
... ...
src/terminal/font/properties.c
... ... @@ -47,11 +47,65 @@ static const gchar * invalid_font_messages[] = {
47 47 const gchar * v3270_get_default_font_name()
48 48 {
49 49 #if defined(_WIN32)
50   - return "Lucida Console";
  50 + {
  51 + HKEY hKey;
  52 + DWORD disp = 0;
  53 + LSTATUS rc = RegCreateKeyEx(
  54 + HKEY_LOCAL_MACHINE,
  55 + "Software\\" LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),
  56 + 0,
  57 + NULL,
  58 + REG_OPTION_NON_VOLATILE,
  59 + KEY_QUERY_VALUE|KEY_READ,
  60 + NULL,
  61 + &hKey,
  62 + &disp);
  63 +
  64 + debug("%s=%d","Software\\" LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME),rc);
  65 +
  66 + if(rc == ERROR_SUCCESS)
  67 + {
  68 + static char * default_font_name = NULL;
  69 + DWORD cbData = 4096;
  70 +
  71 + if(!default_font_name)
  72 + {
  73 + default_font_name = (char *) malloc(cbData+1);
  74 + }
  75 + else
  76 + {
  77 + default_font_name = (char *) realloc(default_font_name,cbData+1);
  78 + }
  79 +
  80 + DWORD dwRet = RegQueryValueEx(hKey,"font-family",NULL,NULL,(LPBYTE) default_font_name, &cbData);
  81 +
  82 + debug("dwRet=%d",dwRet);
  83 +
  84 + RegCloseKey(hKey);
  85 +
  86 + if(dwRet == ERROR_SUCCESS)
  87 + {
  88 + default_font_name = (char *) realloc(default_font_name,cbData+1);
  89 + default_font_name[cbData] = 0;
  90 + return default_font_name;
  91 + }
  92 +
  93 + free(default_font_name);
  94 + default_font_name = NULL;
  95 + }
  96 + }
  97 +
  98 + // TODO: Search for a valid font-family
  99 + return "Courier New";
  100 +
51 101 #elif defined(__APPLE__)
  102 +
52 103 return "Courier New";
  104 +
53 105 #else
  106 +
54 107 return "monospace";
  108 +
55 109 #endif // _WIN32
56 110 }
57 111  
... ... @@ -108,10 +162,7 @@ LIB3270_EXPORT void v3270_set_font_family(GtkWidget *widget, const gchar *name)
108 162 terminal->font.family = g_strdup(name);
109 163 terminal->font.weight = lib3270_get_toggle(terminal->host,LIB3270_TOGGLE_BOLD) ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL;
110 164  
111   - v3270_emit_save_settings(widget);
112   -
113   - debug("%s: %p",__FUNCTION__,GTK_V3270_GET_CLASS(widget)->properties.settings[V3270_SETTING_FONT_FAMILY]);
114   - v3270_notify_setting(widget,V3270_SETTING_FONT_FAMILY);
  165 + v3270_emit_save_settings(widget,"font_family");
115 166  
116 167 if(gtk_widget_get_realized(widget) && gtk_widget_get_has_window(widget))
117 168 {
... ... @@ -123,13 +174,6 @@ LIB3270_EXPORT void v3270_set_font_family(GtkWidget *widget, const gchar *name)
123 174  
124 175 }
125 176  
126   -void v3270_notify_setting(GtkWidget *widget, V3270_SETTING id)
127   -{
128   - debug("%s(%u)",__FUNCTION__,(unsigned int) id);
129   - g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->properties.settings[id]);
130   - v3270_emit_save_settings(widget);
131   -}
132   -
133 177 LIB3270_EXPORT const gchar * v3270_get_font_family(GtkWidget *widget)
134 178 {
135 179 g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
... ...
src/terminal/iocallback.c
... ... @@ -37,7 +37,7 @@ static void * static_AddSource(H3270 *session, int fd, LIB3270_IO_FLAG flag,
37 37 static void static_RemoveSource(H3270 *session, void *id);
38 38 static void static_SetSourceState(H3270 *session, void *id, int enabled);
39 39  
40   -static void * static_AddTimer(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session));
  40 +static void * static_AddTimer(H3270 *session, unsigned long interval_ms, int (*proc)(H3270 *session, void *userdata), void *userdata);
41 41 static void static_RemoveTimer(H3270 *session, void * timer);
42 42 static int static_Sleep(H3270 *hSession, int seconds);
43 43 static int static_RunPendingEvents(H3270 *hSession, int wait);
... ... @@ -48,7 +48,7 @@ static int static_RunPendingEvents(H3270 *hSession, int wait);
48 48 {
49 49 unsigned char remove;
50 50 void * userdata;
51   - int (*call)(H3270 *session);
  51 + int (*call)(H3270 *session, void *userdata);
52 52 H3270 * session;
53 53 } TIMER;
54 54  
... ... @@ -74,17 +74,18 @@ static void static_SetSourceState(G_GNUC_UNUSED H3270 *session, void *id, int en
74 74 static gboolean do_timer(TIMER *t)
75 75 {
76 76 if(!t->remove)
77   - return t->call(t->session) != 0;
  77 + return t->call(t->session,t->userdata);
78 78  
79 79 return FALSE;
80 80 }
81 81  
82   -static void * static_AddTimer(H3270 *session, unsigned long interval, int (*call)(H3270 *session))
  82 +static void * static_AddTimer(H3270 *session, unsigned long interval, int (*call)(H3270 *session, void *userdata), void *userdata)
83 83 {
84 84 TIMER *t = g_malloc0(sizeof(TIMER));
85 85  
86 86 t->call = call;
87 87 t->session = session;
  88 + t->userdata = userdata;
88 89  
89 90 g_timeout_add_full(G_PRIORITY_DEFAULT, (guint) interval, (GSourceFunc) do_timer, t, g_free);
90 91  
... ...
src/terminal/keyfile.c
... ... @@ -308,13 +308,17 @@
308 308 for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
309 309 save_by_pspec(widget,klass->properties.toggle[ix],key_file,group_name);
310 310  
311   - // Save V3270 Responses
312   - for(ix = 0; ix < G_N_ELEMENTS(terminal->responses); ix++)
313   - save_by_pspec(widget,klass->responses[ix],key_file,group_name);
314   -
315 311 // Save V3270 properties
316   - for(ix = 0; ix < V3270_SETTING_COUNT; ix++)
317   - save_by_pspec(widget,klass->properties.settings[ix],key_file,group_name);
  312 + for(ix = 0; klass->properties.persistent[ix];ix++)
  313 + {
  314 + save_by_pspec(
  315 + widget,
  316 + g_object_class_find_property(G_OBJECT_CLASS(klass),klass->properties.persistent[ix]),
  317 + key_file,
  318 + group_name
  319 + );
  320 +
  321 + }
318 322  
319 323 }
320 324  
... ... @@ -360,13 +364,17 @@
360 364 for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
361 365 load_by_pspec(widget,klass->properties.toggle[ix],key_file,group_name);
362 366  
363   - // Load V3270 Responses
364   - for(ix = 0; ix < G_N_ELEMENTS(terminal->responses); ix++)
365   - load_by_pspec(widget,klass->responses[ix],key_file,group_name);
366   -
367 367 // Load V3270 properties
368   - for(ix = 0; ix < V3270_SETTING_COUNT; ix++)
369   - load_by_pspec(widget,klass->properties.settings[ix],key_file,group_name);
  368 + for(ix = 0; klass->properties.persistent[ix];ix++)
  369 + {
  370 + load_by_pspec(
  371 + widget,
  372 + g_object_class_find_property(G_OBJECT_CLASS(klass),klass->properties.persistent[ix]),
  373 + key_file,
  374 + group_name
  375 + );
  376 +
  377 + }
370 378  
371 379 g_object_thaw_notify(G_OBJECT(widget));
372 380 terminal->freeze = 0;
... ...
src/terminal/marshal
... ... @@ -6,6 +6,8 @@ VOID:POINTER
6 6 VOID:VOID,POINTER,POINTER
7 7 VOID:VOID,UINT,POINTER
8 8 BOOLEAN:UINT,ENUM
  9 +UINT:POINTER
  10 +BOOLEAN:POINTER,UINT
9 11 VOID:VOID,BOOLEAN
10 12 BOOLEAN:VOID,BOOLEAN,BOOLEAN,POINTER
11 13 VOID:VOID,UINT,UINT
... ...
src/terminal/properties/get.c
... ... @@ -39,11 +39,13 @@
39 39  
40 40 // debug("%s(%u,%s)",__FUNCTION__,prop_id,g_param_spec_get_name(pspec));
41 41  
  42 + /*
42 43 if(prop_id >= klass->properties.type.responses)
43 44 {
44 45 g_value_set_int(value,(int) window->responses[prop_id - klass->properties.type.responses]);
45 46 }
46   - else if(prop_id >= klass->properties.type.str)
  47 + else */
  48 + if(prop_id >= klass->properties.type.str)
47 49 {
48 50 const LIB3270_STRING_PROPERTY * prop = (lib3270_get_string_properties_list()+(prop_id - klass->properties.type.str));
49 51 // debug("%s.%s.%s",__FUNCTION__,"string",prop->name);
... ... @@ -146,6 +148,11 @@
146 148 case V3270_PROPERTY_HAS_COPY:
147 149 g_value_set_boolean(value,window->selection.blocks != NULL);
148 150 break;
  151 +
  152 + case V3270_PROPERTY_HAS_TIMER:
  153 + g_value_set_boolean(value,window->timer != NULL);
  154 + break;
  155 +
149 156 default:
150 157 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
151 158  
... ...
src/terminal/properties/init.c
... ... @@ -43,15 +43,7 @@
43 43 } properties[] = {
44 44 { "connected", &klass->properties.online },
45 45 { "associated-lu", &klass->properties.associated_lu },
46   - { "url", &klass->properties.settings[V3270_SETTING_URL] },
47   - { "model-number", &klass->properties.settings[V3270_SETTING_MODEL_NUMBER] },
48 46 { "has-selection", &klass->properties.selection },
49   - { "oversize", &klass->properties.settings[V3270_SETTING_OVERSIZE] },
50   - { "host-charset", &klass->properties.settings[V3270_SETTING_HOST_CHARSET] },
51   - { "unlock-delay", &klass->properties.settings[V3270_SETTING_UNLOCK_DELAY] },
52   - { "color-type", &klass->properties.settings[V3270_SETTING_COLOR_TYPE] },
53   - { "host-type", &klass->properties.settings[V3270_SETTING_HOST_TYPE] },
54   - { "crl-preferred-protocol", &klass->properties.settings[V3270_SETTING_CRL_PROTOCOL] },
55 47 };
56 48  
57 49 size_t ix;
... ... @@ -83,7 +75,7 @@
83 75 // Setup internal properties.
84 76  
85 77 // Font family
86   - klass->properties.settings[V3270_SETTING_FONT_FAMILY] =
  78 + spec =
87 79 g_param_spec_string(
88 80 "font_family",
89 81 "font_family",
... ... @@ -95,7 +87,7 @@
95 87 g_object_class_install_property(
96 88 gobject_class,
97 89 V3270_PROPERTY_FONT_FAMILY,
98   - klass->properties.settings[V3270_SETTING_FONT_FAMILY]
  90 + spec
99 91 );
100 92  
101 93 // Session name.
... ... @@ -114,7 +106,7 @@
114 106 );
115 107  
116 108 // Auto disconnect
117   - klass->properties.settings[V3270_SETTING_AUTO_DISCONNECT] =
  109 + spec =
118 110 g_param_spec_uint(
119 111 "auto_disconnect",
120 112 "auto_disconnect",
... ... @@ -128,7 +120,7 @@
128 120 g_object_class_install_property(
129 121 gobject_class,
130 122 V3270_PROPERTY_AUTO_DISCONNECT,
131   - klass->properties.settings[V3270_SETTING_AUTO_DISCONNECT]
  123 + spec
132 124 );
133 125  
134 126 // Clipboard
... ... @@ -147,7 +139,7 @@
147 139 );
148 140  
149 141 // Remap file
150   - klass->properties.settings[V3270_SETTING_REMAP_FILE] =
  142 + spec =
151 143 g_param_spec_string(
152 144 "remap_file",
153 145 "remap_file",
... ... @@ -159,11 +151,11 @@
159 151 g_object_class_install_property(
160 152 gobject_class,
161 153 V3270_PROPERTY_REMAP_FILE,
162   - klass->properties.settings[V3270_SETTING_REMAP_FILE]
  154 + spec
163 155 );
164 156  
165 157 // Dynamic font spacing
166   - klass->properties.settings[V3270_SETTING_DYNAMIC_SPACING] =
  158 + spec =
167 159 g_param_spec_boolean(
168 160 "dynamic_font_spacing",
169 161 "dynamic_font_spacing",
... ... @@ -175,11 +167,11 @@
175 167 g_object_class_install_property(
176 168 gobject_class,
177 169 V3270_PROPERTY_DYNAMIC_SPACING,
178   - klass->properties.settings[V3270_SETTING_DYNAMIC_SPACING]
  170 + spec
179 171 );
180 172  
181 173 // Lu names
182   - klass->properties.settings[V3270_SETTING_LU_NAMES] =
  174 + spec =
183 175 g_param_spec_string(
184 176 "lu_names",
185 177 "lu_names",
... ... @@ -191,7 +183,7 @@
191 183 g_object_class_install_property(
192 184 gobject_class,
193 185 V3270_PROPERTY_LU_NAMES,
194   - klass->properties.settings[V3270_SETTING_LU_NAMES]
  186 + spec
195 187 );
196 188  
197 189 // Trace
... ... @@ -209,7 +201,7 @@
209 201 );
210 202  
211 203 // Colors
212   - klass->properties.settings[V3270_SETTING_TERMINAL_COLORS] =
  204 + spec =
213 205 g_param_spec_string(
214 206 "colors",
215 207 "colors",
... ... @@ -221,11 +213,11 @@
221 213 g_object_class_install_property(
222 214 gobject_class,
223 215 V3270_PROPERTY_TERMINAL_COLORS,
224   - klass->properties.settings[V3270_SETTING_TERMINAL_COLORS]
  216 + spec
225 217 );
226 218  
227 219 // Clipboard options
228   - klass->properties.settings[V3270_SETTING_SELECTION_OPTIONS] =
  220 + spec =
229 221 g_param_spec_uint(
230 222 "selection_flags",
231 223 "selection_flags",
... ... @@ -239,10 +231,9 @@
239 231 g_object_class_install_property(
240 232 gobject_class,
241 233 V3270_PROPERTY_SELECTION_OPTIONS,
242   - klass->properties.settings[V3270_SETTING_SELECTION_OPTIONS]
  234 + spec
243 235 );
244 236  
245   -
246 237 klass->properties.has_copy =
247 238 g_param_spec_boolean(
248 239 "has_copy",
... ... @@ -258,6 +249,20 @@
258 249 klass->properties.has_copy
259 250 );
260 251  
  252 + klass->properties.has_timer =
  253 + g_param_spec_boolean(
  254 + "has_timer",
  255 + "has_timer",
  256 + _( "True if the timer indicator is active" ),
  257 + FALSE,
  258 + G_PARAM_READABLE
  259 + );
  260 +
  261 + g_object_class_install_property(
  262 + gobject_class,
  263 + V3270_PROPERTY_HAS_TIMER,
  264 + klass->properties.has_timer
  265 + );
261 266  
262 267 //
263 268 // Create dynamic properties
... ... @@ -385,6 +390,7 @@
385 390 //
386 391 // Create action properties.
387 392 //
  393 + /*
388 394 klass->properties.type.responses = klass->properties.count;
389 395  
390 396 static const struct
... ... @@ -422,7 +428,7 @@
422 428 }
423 429  
424 430 }
425   -
  431 + */
426 432  
427 433 }
428 434  
... ...
src/terminal/properties/private.h
... ... @@ -59,8 +59,9 @@
59 59 V3270_PROPERTY_TERMINAL_COLORS = 10, ///< @brief Terminal colors.
60 60 V3270_PROPERTY_SELECTION_OPTIONS = 11,
61 61 V3270_PROPERTY_HAS_COPY = 12, ///< @brief Terminal has copy.
  62 + V3270_PROPERTY_HAS_TIMER = 13, ///< @brief Timer indicator state.
62 63  
63   - V3270_PROPERTY_DYNAMIC = 13 ///< @brief Id of the first LIB3270 internal property.
  64 + V3270_PROPERTY_DYNAMIC = 14 ///< @brief Id of the first LIB3270 internal property.
64 65 };
65 66  
66 67 G_GNUC_INTERNAL void v3270_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
... ...
src/terminal/properties/set.c
... ... @@ -29,6 +29,7 @@
29 29  
30 30 #include "private.h"
31 31 #include <v3270/trace.h>
  32 + #include <v3270/settings.h>
32 33  
33 34 /*--[ Implement ]------------------------------------------------------------------------------------*/
34 35  
... ... @@ -256,7 +257,7 @@ LIB3270_EXPORT void v3270_set_auto_disconnect(GtkWidget *widget, guint minutes)
256 257 if(terminal->activity.disconnect != minutes)
257 258 {
258 259 terminal->activity.disconnect = minutes;
259   - v3270_notify_setting(widget,V3270_SETTING_AUTO_DISCONNECT);
  260 + v3270_emit_save_settings(widget,"auto_disconnect");
260 261 }
261 262  
262 263 }
... ... @@ -273,7 +274,7 @@ LIB3270_EXPORT void v3270_set_dynamic_font_spacing(GtkWidget *widget, gboolean s
273 274 terminal->font.spacing.dynamic = state;
274 275 v3270_reconfigure(terminal);
275 276 gtk_widget_queue_draw(widget);
276   - v3270_notify_setting(widget,V3270_SETTING_DYNAMIC_SPACING);
  277 + v3270_emit_save_settings(widget,"dynamic_font_spacing");
277 278 }
278 279  
279 280 }
... ... @@ -282,6 +283,6 @@ LIB3270_EXPORT void v3270_set_lunames(GtkWidget *widget, const gchar *lunames)
282 283 {
283 284 g_return_if_fail(GTK_IS_V3270(widget));
284 285 lib3270_set_lunames(GTK_V3270(widget)->host,(lunames && *lunames ? lunames : NULL));
285   - v3270_notify_setting(widget,V3270_SETTING_LU_NAMES);
  286 + v3270_emit_save_settings(widget,"lu_names");
286 287 }
287 288  
... ...
src/terminal/widget.c
... ... @@ -58,6 +58,26 @@
58 58 *
59 59 */
60 60  
  61 +/// @brief Persistent properties (load/save from session file).
  62 +static const gchar *persistent_properties[] = {
  63 + "url",
  64 + "model-number",
  65 + "oversize",
  66 + "host-charset",
  67 + "unlock-delay",
  68 + "color-type",
  69 + "host-type",
  70 + "crl-preferred-protocol",
  71 + "remap_file",
  72 + "dynamic_font_spacing",
  73 + "lu_names",
  74 + "font_family",
  75 + "auto_disconnect",
  76 + "colors",
  77 + "selection_flags",
  78 + NULL
  79 +};
  80 +
61 81 /*--[ Widget definition ]----------------------------------------------------------------------------*/
62 82  
63 83 G_DEFINE_TYPE(v3270, v3270, GTK_TYPE_WIDGET);
... ... @@ -201,12 +221,14 @@ static void finalize(GObject *object) {
201 221 G_OBJECT_CLASS(v3270_parent_class)->finalize(object);
202 222 }
203 223  
204   -static void v3270_class_init(v3270Class *klass)
205   -{
  224 + static void v3270_class_init(v3270Class *klass)
  225 + {
206 226 GObjectClass * gobject_class = G_OBJECT_CLASS(klass);
207 227 GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass);
208 228 GtkBindingSet * binding = gtk_binding_set_by_class(klass);
209 229  
  230 + klass->properties.persistent = persistent_properties;
  231 +
210 232 // Setup widget key bindings
211 233 gtk_binding_entry_skip(binding,GDK_F10,0);
212 234  
... ... @@ -242,11 +264,11 @@ static void v3270_class_init(v3270Class *klass)
242 264 klass->activate = v3270_activate;
243 265 klass->toggle_changed = v3270_toggle_changed;
244 266 klass->message_changed = v3270_update_message;
245   - klass->popup_message = v3270_popup_message;
246 267  
247 268 // Register I/O Handlers
248 269 v3270_register_io_handlers(klass);
249 270  
  271 +
250 272 // Cursors
251 273 {
252 274 #ifdef WIN32
... ... @@ -428,15 +450,6 @@ static void v3270_class_init(v3270Class *klass)
428 450 v3270_VOID__VOID_UINT_UINT,
429 451 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
430 452  
431   - v3270_widget_signal[V3270_SIGNAL_MESSAGE] =
432   - g_signal_new( I_("popup_message"),
433   - G_OBJECT_CLASS_TYPE (gobject_class),
434   - G_SIGNAL_RUN_FIRST,
435   - G_STRUCT_OFFSET (v3270Class, popup_message),
436   - NULL, NULL,
437   - v3270_VOID__VOID_UINT_POINTER_POINTER_POINTER,
438   - G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
439   -
440 453 v3270_widget_signal[V3270_SIGNAL_FIELD] =
441 454 g_signal_new( I_("field_clicked"),
442 455 G_OBJECT_CLASS_TYPE (gobject_class),
... ... @@ -474,6 +487,24 @@ static void v3270_class_init(v3270Class *klass)
474 487 v3270_VOID__VOID,
475 488 G_TYPE_NONE, 0);
476 489  
  490 + v3270_widget_signal[V3270_SIGNAL_LOAD_POPUP_RESPONSE] =
  491 + g_signal_new( I_("load-popup-response"),
  492 + G_OBJECT_CLASS_TYPE (gobject_class),
  493 + G_SIGNAL_RUN_LAST,
  494 + 0,
  495 + NULL, NULL,
  496 + v3270_UINT__POINTER,
  497 + G_TYPE_UINT, 1, G_TYPE_POINTER);
  498 +
  499 + v3270_widget_signal[V3270_SIGNAL_SAVE_POPUP_RESPONSE] =
  500 + g_signal_new( I_("save-popup-response"),
  501 + G_OBJECT_CLASS_TYPE (gobject_class),
  502 + G_SIGNAL_RUN_LAST,
  503 + 0,
  504 + NULL, NULL,
  505 + v3270_BOOLEAN__POINTER_UINT,
  506 + G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_UINT);
  507 +
477 508 v3270_init_properties(gobject_class);
478 509  
479 510 }
... ... @@ -492,7 +523,7 @@ static void release_activity_timer(v3270 *widget)
492 523  
493 524 static void v3270_init(v3270 *widget)
494 525 {
495   - size_t ix;
  526 + // size_t ix;
496 527  
497 528 widget->host = lib3270_session_new(NULL);
498 529 lib3270_set_user_data(widget->host,widget);
... ... @@ -534,8 +565,10 @@ static void v3270_init(v3270 *widget)
534 565 v3270_font_info_init(&widget->font);
535 566 v3270_set_color_table(widget->color,v3270_get_default_colors());
536 567  
  568 + /*
537 569 for(ix = 0; ix < G_N_ELEMENTS(widget->responses); ix++)
538 570 widget->responses[ix] = GTK_RESPONSE_NONE;
  571 + */
539 572  
540 573 // Init accelerators
541 574 v3270_init_accelerators(widget);
... ... @@ -813,8 +846,11 @@ static gboolean bg_emit_save_settings(v3270 *terminal)
813 846 return FALSE;
814 847 }
815 848  
816   -LIB3270_EXPORT void v3270_emit_save_settings(GtkWidget *widget)
  849 +LIB3270_EXPORT void v3270_emit_save_settings(GtkWidget *widget, const gchar *property_name)
817 850 {
  851 + if(property_name)
  852 + g_object_notify(G_OBJECT(widget),property_name);
  853 +
818 854 debug("%s(Freeze is %s)",__FUNCTION__,GTK_V3270(widget)->freeze ? "ON" : "OFF");
819 855 if(widget && GTK_IS_V3270(widget) && !GTK_V3270(widget)->freeze)
820 856 {
... ...
src/terminal/windows/init.c
... ... @@ -40,9 +40,13 @@
40 40  
41 41 BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwcallpurpose, LPVOID G_GNUC_UNUSED(lpvResvd))
42 42 {
  43 + debug("%s starts",__FUNCTION__);
  44 +
  45 + /*
43 46 switch(dwcallpurpose)
44 47 {
45 48 case DLL_PROCESS_ATTACH:
  49 + debug("%s: DLL_PROCESS_ATTACH",__FUNCTION__);
46 50 {
47 51 char lpFilename[4096];
48 52  
... ... @@ -58,14 +62,16 @@ BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwcallpurpose, LPVOID G_GNUC_UNUSED(
58 62  
59 63 bindtextdomain(GETTEXT_PACKAGE,lpFilename);
60 64 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
61   -
62 65 }
63 66 break;
64 67  
65 68 case DLL_PROCESS_DETACH:
  69 + debug("%s: DLL_PROCESS_DETACH",__FUNCTION__);
66 70 break;
67 71  
68 72 }
  73 + */
69 74  
  75 + debug("%s ends",__FUNCTION__);
70 76 return TRUE;
71 77 }
... ...
src/terminal/windows/registry.c
... ... @@ -263,10 +263,6 @@
263 263 for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
264 264 save_by_pspec(widget,klass->properties.toggle[ix],hKey);
265 265  
266   - // Save V3270 Responses
267   - for(ix = 0; ix < G_N_ELEMENTS(terminal->responses); ix++)
268   - save_by_pspec(widget,klass->responses[ix],hKey);
269   -
270 266 // Save V3270 properties
271 267 for(ix = 0; ix < V3270_SETTING_COUNT; ix++)
272 268 save_by_pspec(widget,klass->properties.settings[ix],hKey);
... ... @@ -328,10 +324,6 @@
328 324 for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
329 325 load_by_pspec(widget,klass->properties.toggle[ix],hKey);
330 326  
331   - // Load V3270 Responses
332   - for(ix = 0; ix < G_N_ELEMENTS(terminal->responses); ix++)
333   - load_by_pspec(widget,klass->responses[ix],hKey);
334   -
335 327 // Load V3270 properties
336 328 for(ix = 0; ix < V3270_SETTING_COUNT; ix++)
337 329 load_by_pspec(widget,klass->properties.settings[ix],hKey);
... ...
src/testprogram/testprogram.c
... ... @@ -71,35 +71,6 @@
71 71 }
72 72 */
73 73  
74   -#ifdef _WIN32
75   -
76   - static int get_registry(HKEY *hKey,REGSAM samDesired)
77   - {
78   - DWORD disp;
79   -
80   - if(RegCreateKeyEx(HKEY_CURRENT_USER,"software\\v3270",0,NULL,REG_OPTION_NON_VOLATILE,samDesired,NULL,hKey,&disp) != ERROR_SUCCESS)
81   - {
82   - g_warning("Can't open registry");
83   - return -1;
84   - }
85   -
86   - return 0;
87   -
88   - }
89   -
90   - static void save_settings(GtkWidget *terminal, GtkWidget *window)
91   - {
92   - HKEY hKey = 0;
93   -
94   - if(get_registry(&hKey,KEY_SET_VALUE))
95   - return;
96   -
97   - v3270_to_registry(terminal,hKey,"terminal");
98   - RegCloseKey(hKey);
99   - }
100   -
101   -#else
102   -
103 74 static GKeyFile * get_key_file()
104 75 {
105 76 GKeyFile * key_file = g_key_file_new();
... ... @@ -109,7 +80,7 @@
109 80  
110 81 static void save_settings(GtkWidget *terminal, GtkWidget *window)
111 82 {
112   - debug("%s: Saving settings for windows %p",__FUNCTION__,window);
  83 + debug("%s: Saving settings for window %p",__FUNCTION__,window);
113 84  
114 85 GKeyFile * key_file = get_key_file();
115 86  
... ... @@ -122,8 +93,6 @@
122 93  
123 94 }
124 95  
125   -#endif // _WIN32
126   -
127 96 static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) {
128 97  
129 98 GtkWidget * window = gtk_application_window_new(app);
... ... @@ -132,7 +101,7 @@
132 101 GtkWidget * notebook = gtk_notebook_new();
133 102  
134 103 // Hack to speed up the tests.
135   - lib3270_disable_crl_download(v3270_get_session(terminal));
  104 + lib3270_ssl_set_crl_download(v3270_get_session(terminal),0);
136 105  
137 106 gtk_box_pack_start(GTK_BOX(vBox),create_toolbar(terminal),FALSE,TRUE,0);
138 107 gtk_box_pack_start(GTK_BOX(vBox),notebook,TRUE,TRUE,0);
... ... @@ -147,32 +116,12 @@
147 116  
148 117 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),terminal,gtk_label_new("Terminal"));
149 118  
150   -#ifdef _WIN32
151   - v3270_set_font_family(terminal,"Lucida Console");
152   -#endif // _WIN32
153   -
154   - v3270_selection_set_font_family(terminal,"monospace");
155   -
156 119 // Load settings before connecting the signals.
157   -#ifdef _WIN32
158   - {
159   - HKEY hKey = 0;
160   -
161   - if(!get_registry(&hKey,KEY_SET_VALUE))
162   - {
163   - v3270_load_registry(terminal,hKey,"terminal");
164   - RegCloseKey(hKey);
165   - }
166   -
167   - }
168   -#else
169 120 debug("%s: Loading settings...",__FUNCTION__);
170 121 GKeyFile * key_file = get_key_file();
171 122 v3270_load_key_file(terminal,key_file,NULL);
172 123 v3270_accelerator_map_load_key_file(terminal,key_file,NULL);
173   -
174 124 g_key_file_free(key_file);
175   -#endif // _WIN32
176 125  
177 126 }
178 127  
... ...
src/testprogram/toolbar.c
... ... @@ -37,6 +37,7 @@
37 37 #include <v3270/selection.h>
38 38 #include <v3270/trace.h>
39 39 #include <lib3270/log.h>
  40 + #include <lib3270/popup.h>
40 41 #include <stdlib.h>
41 42  
42 43 #pragma GCC diagnostic ignored "-Wunused-parameter"
... ... @@ -103,9 +104,13 @@
103 104 lib3270_disconnect(v3270_get_session(terminal));
104 105 }
105 106  
106   - static void save_all_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal)
  107 + static void save_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal)
107 108 {
108   - lib3270_save_all(v3270_get_session(terminal),NULL);
  109 + H3270 *hSession = v3270_get_session(terminal);
  110 + if(lib3270_get_has_selection(hSession))
  111 + lib3270_save_selected(hSession,NULL);
  112 + else
  113 + lib3270_save_all(hSession,NULL);
109 114 }
110 115  
111 116 static void load_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal)
... ... @@ -159,6 +164,7 @@
159 164 */
160 165  
161 166  
  167 + /*
162 168 {
163 169 //
164 170 // Test V3270 FT Dialog
... ... @@ -176,7 +182,24 @@
176 182 gtk_widget_show_all(dialog);
177 183  
178 184 }
  185 + */
  186 +
179 187  
  188 + }
  189 +
  190 + static void popup_clicked(GtkButton *button, GtkWidget *terminal)
  191 + {
  192 +
  193 + /*
  194 + static const LIB3270_POPUP popup = {
  195 + .name = "sample_popup",
  196 + .type = LIB3270_NOTIFY_INFO,
  197 + .summary = "This is the summary of message",
  198 + .body = "This it the body of the message, can be used for a bigger explanation"
  199 + };
  200 +
  201 + lib3270_popup(v3270_get_session(terminal), &popup, 1);
  202 + */
180 203  
181 204 }
182 205  
... ... @@ -226,8 +249,9 @@
226 249 { "gtk-harddisk", G_CALLBACK(ft_clicked), "Open file transfer dialog" },
227 250 { "gtk-copy", G_CALLBACK(copy_clicked), "Copy data" },
228 251 { "gtk-paste", G_CALLBACK(paste_clicked), "Paste data" },
229   - { "document-save", G_CALLBACK(save_all_clicked), "Save screen" },
  252 + { "document-save", G_CALLBACK(save_clicked), "Save screen or selection" },
230 253 { "document-open", G_CALLBACK(load_clicked), "Paste file" },
  254 + { "dialog-information", G_CALLBACK(popup_clicked), "Show test popup" },
231 255  
232 256 { "applications-system", G_CALLBACK(preferences_clicked), "Session properties" },
233 257  
... ...
v3270.cbp
... ... @@ -217,6 +217,9 @@
217 217 <Unit filename="src/selection/linux/paste.c">
218 218 <Option compilerVar="CC" />
219 219 </Unit>
  220 + <Unit filename="src/selection/pixbuf.c">
  221 + <Option compilerVar="CC" />
  222 + </Unit>
220 223 <Unit filename="src/selection/selection.c">
221 224 <Option compilerVar="CC" />
222 225 </Unit>
... ... @@ -358,6 +361,7 @@
358 361 <Unit filename="src/terminal/linux/iosource.c">
359 362 <Option compilerVar="CC" />
360 363 </Unit>
  364 + <Unit filename="src/terminal/marshal" />
361 365 <Unit filename="src/terminal/marshal.h" />
362 366 <Unit filename="src/terminal/mouse.c">
363 367 <Option compilerVar="CC" />
... ... @@ -417,9 +421,6 @@
417 421 <Option compilerVar="CC" />
418 422 </Unit>
419 423 <Extensions>
420   - <code_completion />
421   - <envvars />
422   - <debugger />
423 424 <lib_finder disable_auto="1" />
424 425 </Extensions>
425 426 </Project>
... ...