Commit cad6def6474ad8b9765ef6b6eb039e146c75a278

Authored by Perry Werneck
Committed by GitHub
2 parents a8f72c8e a8f2e87c

Merge pull request #12 from PerryWerneck/develop

Updating to latest code from develop. Many fixes and enhancements.
Showing 58 changed files with 3907 additions and 1817 deletions   Show diff stats
.gitignore
... ... @@ -57,6 +57,9 @@ src/include/lib3270
57 57 vgcore.*
58 58 gschemas.compiled
59 59 *.gschema.xml
  60 +appdata.xml
  61 +*.[0-9]
  62 +
60 63 *.3270
61 64 macos/**/*.app
62 65 mime.xml
... ...
Makefile.in
... ... @@ -38,8 +38,9 @@ SOURCES= \
38 38 $(wildcard src/objects/terminal/*.c) \
39 39 $(wildcard src/objects/toolbar/*.c) \
40 40 $(wildcard src/objects/settings/*.c) \
41   - $(wildcard src/objects/@OSNAME@/*.c) \
  41 + $(wildcard src/objects/os/@OSNAME@/*.c) \
42 42 $(wildcard src/main/*.c) \
  43 + $(wildcard src/tools/*.c) \
43 44 $(wildcard src/main/@OSNAME@/*.c) \
44 45 $(wildcard src/main/@OSNAME@/*.rc) \
45 46 $(wildcard src/objects/keypad/*.c)
... ... @@ -63,6 +64,7 @@ WINDRES=@WINDRES@
63 64 AR=@AR@
64 65 VALGRIND=@VALGRIND@
65 66 CONVERT=@CONVERT@
  67 +STRIP=@STRIP@
66 68  
67 69 #---[ Paths ]----------------------------------------------------------------------------
68 70  
... ... @@ -127,6 +129,11 @@ $(OBJDBG)/%.o: \
127 129  
128 130 @$(CC) \
129 131 $(CFLAGS) \
  132 + -DDEBUG=1 \
  133 + -MM -MT $@ -MF $(patsubst %.o,%.d,$@) $<
  134 +
  135 + @$(CC) \
  136 + $(CFLAGS) \
130 137 -Wall -Wextra -fstack-check \
131 138 -DDEBUG=1 \
132 139 -o $@ -c $<
... ... @@ -154,6 +161,12 @@ $(OBJRLS)/%.o: \
154 161  
155 162 @echo $< ...
156 163 @$(MKDIR) $(dir $@)
  164 +
  165 + @$(CC) \
  166 + $(CFLAGS) \
  167 + -DNDEBUG=1 \
  168 + -MM -MT $@ -MF $(patsubst %.o,%.d,$@) $<
  169 +
157 170 @$(CC) \
158 171 $(CFLAGS) \
159 172 -DNDEBUG=1 \
... ... @@ -179,6 +192,7 @@ $(POTDIR)/$(PACKAGE_NAME)/%.pot: \
179 192 --keyword=_ \
180 193 --keyword=N_ \
181 194 --keyword=MSG_:2 \
  195 + --keyword=NC_:1c,2 \
182 196 --output=$@ \
183 197 $<
184 198 @touch $@
... ... @@ -258,6 +272,10 @@ $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@: \
258 272 $^ \
259 273 $(LIBS)
260 274  
  275 +strip: \
  276 + $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@
  277 +
  278 + @$(STRIP) --discard-all $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@
261 279  
262 280 #---[ Install Targets ]------------------------------------------------------------------
263 281  
... ... @@ -266,18 +284,11 @@ install: \
266 284 install-keypads
267 285  
268 286 install-application: \
269   - $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@ \
  287 + install-@OSNAME@-application \
270 288 install-locale \
271 289 install-schemas \
272   - install-branding
273   -
274   - @$(MKDIR) \
275   - $(DESTDIR)/$(bindir)
276   -
277   - @$(INSTALL_PROGRAM) \
278   - $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@ \
279   - $(DESTDIR)/$(bindir)/$(PRODUCT_NAME)@EXEEXT@
280   -
  290 + install-branding \
  291 + install-icons
281 292  
282 293 @$(MKDIR) \
283 294 $(DESTDIR)/$(libdir)/$(PRODUCT_NAME)-plugins
... ... @@ -292,6 +303,28 @@ install-application: \
292 303 @$(MKDIR) \
293 304 $(DESTDIR)/$(datarootdir)/$(PRODUCT_NAME)/keypad
294 305  
  306 +install-linux-application: \
  307 + $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@
  308 +
  309 + @$(MKDIR) \
  310 + $(DESTDIR)/$(bindir)
  311 +
  312 + @$(INSTALL_PROGRAM) \
  313 + $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@ \
  314 + $(DESTDIR)/$(bindir)/$(PRODUCT_NAME)@EXEEXT@
  315 +
  316 +
  317 +install-windows-application: \
  318 + strip
  319 +
  320 + @$(MKDIR) \
  321 + $(DESTDIR)/$(bindir)
  322 +
  323 + @$(INSTALL_PROGRAM) \
  324 + $(BINRLS)/$(PACKAGE_NAME)@EXEEXT@ \
  325 + $(DESTDIR)/$(bindir)/$(PRODUCT_NAME)@EXEEXT@
  326 +
  327 +
295 328 install-keypads:
296 329  
297 330 @$(MKDIR) \
... ... @@ -301,6 +334,15 @@ install-keypads:
301 334 keypad/*.xml \
302 335 $(DESTDIR)/$(datarootdir)/$(PRODUCT_NAME)/keypad
303 336  
  337 +install-icons:
  338 +
  339 + @$(MKDIR) \
  340 + $(DESTDIR)/$(datarootdir)/$(PRODUCT_NAME)/icons
  341 +
  342 + @$(INSTALL_DATA) \
  343 + icons/*.svg \
  344 + $(DESTDIR)/$(datarootdir)/$(PRODUCT_NAME)/icons
  345 +
304 346 #---[ Misc Targets ]---------------------------------------------------------------------
305 347  
306 348 locale/$(PACKAGE_NAME).pot: \
... ... @@ -335,6 +377,14 @@ run: \
335 377 @G_DEBUG=fatal-warnings \
336 378 $(BINDBG)/$(PACKAGE_NAME)@EXEEXT@
337 379  
  380 +
  381 +run-inspector: \
  382 + $(BINDBG)/$(PACKAGE_NAME)@EXEEXT@ \
  383 + gschemas.compiled
  384 +
  385 + @GTK_DEBUG=interactive \
  386 + $(BINDBG)/$(PACKAGE_NAME)@EXEEXT@
  387 +
338 388 mem-check: \
339 389 $(BINDBG)/$(PACKAGE_NAME)@EXEEXT@
340 390  
... ... @@ -382,4 +432,6 @@ clean: \
382 432 cleanDebug \
383 433 cleanRelease
384 434  
  435 +-include $(foreach SRC, $(basename $(SOURCES)), $(OBJDBG)/$(SRC).d)
  436 +-include $(foreach SRC, $(basename $(SOURCES)), $(OBJRLS)/$(SRC).d)
385 437  
... ...
branding/Makefile.in
... ... @@ -44,6 +44,8 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@
44 44 CONVERT=@CONVERT@
45 45 OPTIPNG=@OPTIPNG@
46 46 DESKTOP_INSTALL=@DESKTOP_INSTALL@
  47 +SCOUR=@SCOUR@
  48 +APPSTREAMCLI=@APPSTREAMCLI@
47 49  
48 50 #---[ Rules ]----------------------------------------------------------------------------
49 51  
... ... @@ -107,6 +109,20 @@ $(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/%.png: \
107 109 @$(MKDIR) `dirname $@`
108 110 @$(INSTALL_DATA) $< $@
109 111  
  112 +$(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/icons/%.svg: \
  113 + %.svg
  114 +
  115 + @echo $@ ...
  116 + @$(MKDIR) `dirname $@`
  117 +
  118 +ifeq ($(SCOUR),no)
  119 + @$(INSTALL_DATA) $< $@
  120 +else
  121 + @$(SCOUR) -i $< -o $@
  122 +endif
  123 +
  124 + @chmod 644 $@
  125 +
110 126 $(DESTDIR)$(datarootdir)/pixmaps/%.png: \
111 127 $(BINDIR)/%.png
112 128  
... ... @@ -114,11 +130,19 @@ $(DESTDIR)$(datarootdir)/pixmaps/%.png: \
114 130 @$(MKDIR) `dirname $@`
115 131 @$(INSTALL_DATA) $< $@
116 132  
  133 +validate:
  134 +
  135 +ifneq ($(SCOUR),no)
  136 + @$(APPSTREAMCLI) validate appdata.xml
  137 +endif
  138 +
  139 +
117 140 install: \
118 141 install-@OSNAME@
119 142  
120 143 install-linux: \
121 144 $(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/$(PRODUCT_NAME).png \
  145 + $(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/icons/$(PRODUCT_NAME).svg \
122 146 $(DESTDIR)$(datarootdir)/pixmaps/$(PRODUCT_NAME).png \
123 147 $(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/$(PRODUCT_NAME)-logo.png
124 148  
... ... @@ -138,6 +162,12 @@ install-linux: \
138 162 mime.xml \
139 163 $(DESTDIR)$(datarootdir)/mime/packages/$(PRODUCT_NAME).xml
140 164  
  165 + @$(MKDIR) $(DESTDIR)$(datarootdir)/appdata
  166 +
  167 + @$(INSTALL_DATA) \
  168 + appdata.xml \
  169 + $(DESTDIR)$(datarootdir)/appdata/$(PRODUCT_NAME).appdata.xml
  170 +
141 171 install-windows: \
142 172 $(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/$(PRODUCT_NAME).png \
143 173 $(DESTDIR)$(datarootdir)/$(PRODUCT_NAME)/$(PRODUCT_NAME)-logo.png \
... ...
branding/appdata.xml.in 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<component type="desktop">
  3 + <id>br.com.bb.pw3270</id>
  4 + <name>3270 Terminal</name>
  5 + <name xml:lang="pt_BR">Terminal 3270</name>
  6 + <summary>IBM 3270 Terminal emulator</summary>
  7 + <summary xml:lang="pt_BR">Emulador de terminal IBM 3270</summary>
  8 + <developer_name>perry.werneck@gmail.com</developer_name>
  9 + <description>
  10 + <p>
  11 + GTK Based 3270 terminal emulator
  12 + pw3270 is a modern, GTK-based, completely free tn3270 emulator.
  13 +
  14 + Created originally for Banco do Brasil, it's now an official Brazilian Government Public Software project, and is used worldwide.
  15 + </p>
  16 + </description>
  17 +
  18 + <metadata_license>CC0-1.0</metadata_license>
  19 + <project_license>LGPL-3.0</project_license>
  20 +
  21 + <url type="bugtracker">https://github.com/PerryWerneck/pw3270/issues</url>
  22 + <url type="homepage">https://github.com/PerryWerneck/pw3270</url>
  23 + <project_group>GNOME</project_group>
  24 +
  25 + <launchable type="desktop-id">@PRODUCT_NAME@.desktop</launchable>
  26 +
  27 + <screenshots>
  28 + <screenshot type="default">
  29 + <caption>@PRODUCT_NAME@</caption>
  30 + <image height="600" width="600">https://raw.githubusercontent.com/PerryWerneck/pw3270/master/branding/pw3270-logo.svg</image>
  31 + </screenshot>
  32 + </screenshots>
  33 +
  34 + <update_contact>perry.werneck@gmail.com</update_contact>
  35 +
  36 + <provides>
  37 + <id>@PRODUCT_NAME@pw32.desktop</id>
  38 + </provides>
  39 +</component>
... ...
branding/launcher.desktop.in
... ... @@ -3,9 +3,10 @@ X-SuSE-translate=true
3 3 GenericName=@PRODUCT_NAME@
4 4 Name=3270 Terminal
5 5 Name[pt_BR]=Terminal 3270
6   -Comment=@PACKAGE_DESCRIPTION@
  6 +Comment=IBM 3270 Terminal emulator
  7 +Comment[pt_BR]=Emulador de terminal IBM 3270
7 8 Exec=@PRODUCT_NAME@ %u
8   -Icon=@PRODUCT_NAME@
  9 +Icon=/usr/share/@PRODUCT_NAME@/icons/@PRODUCT_NAME@.svg
9 10 Terminal=false
10 11 Type=Application
11 12 StartupNotify=true
... ...
configure.ac
... ... @@ -67,7 +67,7 @@ case &quot;$host&quot; in
67 67  
68 68 CFLAGS="$CFLAGS -pthread -D_WIN32_WINNT=0x0600"
69 69 LDFLAGS="$LDFLAGS -pthread"
70   - LIBS="$LIBS -lws2_32 -lwtsapi32 -lcomdlg32"
  70 + LIBS="$LIBS -lws2_32 -lwtsapi32 -lcomdlg32 -lole32 -luuid"
71 71  
72 72 app_win32_revision=$(date +%-y.%-m.%-d.%-H)
73 73 AC_SUBST(WIN32_VERSION,$app_win32_revision)
... ... @@ -141,6 +141,10 @@ AC_PATH_TOOL([MSGMERGE], [msgmerge], [no])
141 141 AC_PATH_TOOL([MSGFMT], [msgfmt], [no])
142 142 AC_PATH_TOOL([VALGRIND], [valgrind], [no])
143 143  
  144 +AC_PATH_TOOL([SCOUR], [scour], [no])
  145 +AC_PATH_TOOL([APPSTREAMCLI],[appstreamcli], [no])
  146 +AC_PATH_TOOL([STRIP], [strip], [true])
  147 +
144 148 AC_PATH_TOOL([DESKTOP_INSTALL],[desktop-file-install],[no])
145 149  
146 150 PKG_CHECK_EXISTS
... ... @@ -245,6 +249,7 @@ AC_CONFIG_FILES(locale/Makefile)
245 249 AC_CONFIG_FILES(branding/Makefile)
246 250 AC_CONFIG_FILES(branding/launcher.desktop)
247 251 AC_CONFIG_FILES(branding/mime.xml)
  252 +AC_CONFIG_FILES(branding/appdata.xml)
248 253  
249 254 dnl ---------------------------------------------------------------------------
250 255 dnl Output the generated config.status script.
... ...
icons/gtk-connect-symbolic.svg 0 → 100644
... ... @@ -0,0 +1,84 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<svg
  3 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  4 + xmlns:cc="http://creativecommons.org/ns#"
  5 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  6 + xmlns:svg="http://www.w3.org/2000/svg"
  7 + xmlns="http://www.w3.org/2000/svg"
  8 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  9 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  10 + version="1.1"
  11 + id="svg851"
  12 + width="256"
  13 + height="256"
  14 + viewBox="0 0 256 256"
  15 + sodipodi:docname="gtk-connect-symbolic.svg"
  16 + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
  17 + <metadata
  18 + id="metadata857">
  19 + <rdf:RDF>
  20 + <cc:Work
  21 + rdf:about="">
  22 + <dc:format>image/svg+xml</dc:format>
  23 + <dc:type
  24 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  25 + <dc:title></dc:title>
  26 + </cc:Work>
  27 + </rdf:RDF>
  28 + </metadata>
  29 + <defs
  30 + id="defs855">
  31 + <marker
  32 + style="overflow:visible"
  33 + id="Arrow1Lstart"
  34 + refX="0.0"
  35 + refY="0.0"
  36 + orient="auto"
  37 + inkscape:stockid="Arrow1Lstart"
  38 + inkscape:isstock="true">
  39 + <path
  40 + transform="scale(0.8) translate(12.5,0)"
  41 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
  42 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  43 + id="path1007" />
  44 + </marker>
  45 + </defs>
  46 + <sodipodi:namedview
  47 + pagecolor="#ffffff"
  48 + bordercolor="#666666"
  49 + borderopacity="1"
  50 + objecttolerance="10"
  51 + gridtolerance="10"
  52 + guidetolerance="10"
  53 + inkscape:pageopacity="0"
  54 + inkscape:pageshadow="2"
  55 + inkscape:window-width="1366"
  56 + inkscape:window-height="713"
  57 + id="namedview853"
  58 + showgrid="false"
  59 + inkscape:zoom="1.3921165"
  60 + inkscape:cx="99.069109"
  61 + inkscape:cy="184.6652"
  62 + inkscape:window-x="0"
  63 + inkscape:window-y="25"
  64 + inkscape:window-maximized="1"
  65 + inkscape:current-layer="g859"
  66 + inkscape:document-rotation="0" />
  67 + <g
  68 + inkscape:groupmode="layer"
  69 + inkscape:label="Image"
  70 + id="g859">
  71 + <g
  72 + id="g923"
  73 + transform="matrix(3.7795276,0,0,3.7795276,-118.40429,8.6123775)">
  74 + <path
  75 + id="rect883-3"
  76 + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.858311;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  77 + d="m 92.554935,8.5779117 c -1.798383,-0.1481724 -3.650627,1.2722474 -3.264892,3.1739583 0,13.525103 0,27.050206 0,40.575309 -0.01033,1.949711 3.647396,3.05186 4.472053,1.706431 0,-15.097123 0,-30.194245 0,-45.2913683 -0.392532,-0.1087998 -0.799794,-0.1644515 -1.207161,-0.16433 z m 4.073796,-9.29504033 c -2.07079,-0.0714654 -3.476923,2.03267503 -3.165182,3.95774393 0.01085,19.2643707 -0.0217,38.5298257 0.01628,57.7935187 0.126716,2.110405 2.653929,3.534377 4.522972,2.533701 0,-21.322901 0,-42.645803 0,-63.96870376 -0.426607,-0.20655366 -0.89981,-0.31703838 -1.374071,-0.31625987 z" />
  78 + <path
  79 + id="path930-7"
  80 + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.11486;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  81 + d="M 82.489067,12.90927 A 15.467497,18.678622 0 0 0 68.038271,24.929209 H 52.736878 c -1.91384,0 -3.45457,1.540729 -3.45457,3.454569 v 6.097817 c 0,1.913843 1.54073,3.454572 3.45457,3.454572 h 15.205791 a 15.467497,18.678622 0 0 0 14.546398,12.330512 15.467497,18.678622 0 0 0 7.232118,-2.168342 V 15.077612 A 15.467497,18.678622 0 0 0 82.489067,12.90927 Z" />
  82 + </g>
  83 + </g>
  84 +</svg>
... ...
icons/gtk-disconnect-symbolic.svg 0 → 100644
... ... @@ -0,0 +1,84 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<svg
  3 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  4 + xmlns:cc="http://creativecommons.org/ns#"
  5 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  6 + xmlns:svg="http://www.w3.org/2000/svg"
  7 + xmlns="http://www.w3.org/2000/svg"
  8 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  9 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  10 + version="1.1"
  11 + id="svg851"
  12 + width="256"
  13 + height="256"
  14 + viewBox="0 0 256 256"
  15 + sodipodi:docname="gtk-disconnect-symbolic.svg"
  16 + inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
  17 + <metadata
  18 + id="metadata857">
  19 + <rdf:RDF>
  20 + <cc:Work
  21 + rdf:about="">
  22 + <dc:format>image/svg+xml</dc:format>
  23 + <dc:type
  24 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  25 + <dc:title></dc:title>
  26 + </cc:Work>
  27 + </rdf:RDF>
  28 + </metadata>
  29 + <defs
  30 + id="defs855">
  31 + <marker
  32 + style="overflow:visible"
  33 + id="Arrow1Lstart"
  34 + refX="0.0"
  35 + refY="0.0"
  36 + orient="auto"
  37 + inkscape:stockid="Arrow1Lstart"
  38 + inkscape:isstock="true">
  39 + <path
  40 + transform="scale(0.8) translate(12.5,0)"
  41 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
  42 + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
  43 + id="path1007" />
  44 + </marker>
  45 + </defs>
  46 + <sodipodi:namedview
  47 + pagecolor="#ffffff"
  48 + bordercolor="#666666"
  49 + borderopacity="1"
  50 + objecttolerance="10"
  51 + gridtolerance="10"
  52 + guidetolerance="10"
  53 + inkscape:pageopacity="0"
  54 + inkscape:pageshadow="2"
  55 + inkscape:window-width="1366"
  56 + inkscape:window-height="713"
  57 + id="namedview853"
  58 + showgrid="false"
  59 + inkscape:zoom="1.3921165"
  60 + inkscape:cx="108.83539"
  61 + inkscape:cy="125.36992"
  62 + inkscape:window-x="0"
  63 + inkscape:window-y="25"
  64 + inkscape:window-maximized="1"
  65 + inkscape:current-layer="g859"
  66 + inkscape:document-rotation="0" />
  67 + <g
  68 + inkscape:groupmode="layer"
  69 + inkscape:label="Image"
  70 + id="g859">
  71 + <g
  72 + id="g927"
  73 + transform="matrix(3.7795276,0,0,3.7795276,-161.57965,-402.67362)">
  74 + <path
  75 + id="rect883-3-6"
  76 + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.858311;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  77 + d="m 103.7142,117.39733 c -1.79838,-0.14817 -3.65063,1.27225 -3.26489,3.17396 0,13.5251 0,27.0502 0,40.5753 -0.0103,1.94971 3.6474,3.05189 4.47205,1.70644 0,-15.09713 0,-30.19425 0,-45.29137 -0.39253,-0.1088 -0.79979,-0.16445 -1.20716,-0.16433 z m 4.0738,-9.29504 c -2.07079,-0.0715 -3.47692,2.03267 -3.16518,3.95774 0.0108,19.26437 -0.0217,38.52983 0.0163,57.79352 0.12672,2.11041 2.65393,3.53439 4.52297,2.5337 0,-21.3229 0,-42.6458 0,-63.9687 -0.42661,-0.20656 -0.89981,-0.31704 -1.37407,-0.31626 z" />
  78 + <path
  79 + id="path930"
  80 + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.11486;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
  81 + d="M 77.280561,122.17098 A 15.467497,18.678622 0 0 0 62.829766,134.19091 H 47.528374 c -1.913834,0 -3.45457,1.54073 -3.45457,3.45457 v 6.09782 c 0,1.91384 1.540736,3.45457 3.45457,3.45457 h 15.20579 a 15.467497,18.678622 0 0 0 14.546397,12.33051 15.467497,18.678622 0 0 0 7.463112,-2.3182 v -4.08812 h 8.846487 c 1.75914,0 3.175,-1.41638 3.175,-3.17552 v -2.35489 c 0,-1.75914 -1.41586,-3.17552 -3.175,-3.17552 h -8.846487 v -7.1329 h 8.901264 c 1.759143,0 3.175518,-1.41638 3.175518,-3.17552 v -2.35489 c 0,-1.75914 -1.416375,-3.17552 -3.175518,-3.17552 h -8.901264 v -4.0876 a 15.467497,18.678622 0 0 0 -7.463112,-2.31872 z" />
  82 + </g>
  83 + </g>
  84 +</svg>
... ...
locale/pt_BR.po
... ... @@ -5,8 +5,8 @@ msgid &quot;&quot;
5 5 msgstr ""
6 6 "Project-Id-Version: pw3270 5.0\n"
7 7 "Report-Msgid-Bugs-To: \n"
8   -"POT-Creation-Date: 2020-08-05 16:03-0300\n"
9   -"PO-Revision-Date: 2020-06-06 11:11-0300\n"
  8 +"POT-Creation-Date: 2020-10-15 13:43-0300\n"
  9 +"PO-Revision-Date: 2020-10-15 13:45-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"
... ... @@ -20,17 +20,37 @@ msgstr &quot;&quot;
20 20 "11) ? 2 : 3;\n"
21 21 "X-Generator: Gtranslator 2.91.7\n"
22 22  
23   -#: src/objects/application/application.c:208
  23 +#: src/objects/application/application.c:206
24 24 #, c-format
25 25 msgid "\"%s\" is not a valid user interface name"
26 26 msgstr "\"%s\" não é um nome válido para interface de usuário"
27 27  
28   -#: src/objects/application/actions/about.c:96
  28 +#: src/objects/application/actions/about.c:93
  29 +msgid "32 bits Linux"
  30 +msgstr "Linux 32 bits"
  31 +
  32 +#: src/objects/application/actions/about.c:91
  33 +msgid "32 bits Windows"
  34 +msgstr "Windows 32 bits"
  35 +
  36 +#: src/objects/actions/save.c:156 src/objects/os/linux/savedesktopicon.c:267
  37 +msgid "3270 session files"
  38 +msgstr "Arquivos de sessão TN3270"
  39 +
  40 +#: src/objects/application/actions/about.c:87
29 41 #, c-format
30   -msgid "3270 terminal emulator for GTK %d.%d"
31   -msgstr "Emulador 3270 para GTK+ %d.%d"
  42 +msgid "3270 terminal emulator for %s."
  43 +msgstr "Emulador 3270 para %s"
  44 +
  45 +#: src/objects/application/actions/about.c:95
  46 +msgid "64 bits Linux"
  47 +msgstr "Linux 64 bits"
  48 +
  49 +#: src/objects/application/actions/about.c:89
  50 +msgid "64 bits Windows"
  51 +msgstr "Windows 64 bits"
32 52  
33   -#: src/objects/application/actions/about.c:161 ui/application.xml:39
  53 +#: src/objects/application/actions/about.c:188 ui/application.xml:39
34 54 #: ui/application.xml:537
35 55 msgid "About PW3270"
36 56 msgstr "Sobre o PW3270"
... ... @@ -39,23 +59,23 @@ msgstr &quot;Sobre o PW3270&quot;
39 59 msgid "Action Name"
40 60 msgstr "Nome da ação"
41 61  
42   -#: src/objects/window/window.c:163 src/objects/toolbar/toolbar.c:135
  62 +#: src/objects/window/window.c:184
43 63 msgid "Action Names"
44 64 msgstr "Nome das ações"
45 65  
46   -#: ui/window.xml:369 ui/window.xml:479 ui/application.xml:509
  66 +#: ui/window.xml:379 ui/window.xml:494 ui/application.xml:509
47 67 msgid "Alert sound"
48 68 msgstr "Aviso sonoro"
49 69  
50   -#: src/main/tools.c:99
  70 +#: src/main/tools.c:99 src/tools/entry.c:88
51 71 msgid "All files"
52 72 msgstr "Todos os arquivos"
53 73  
54   -#: ui/window.xml:168 ui/application.xml:251
  74 +#: ui/window.xml:178 ui/application.xml:251
55 75 msgid "Append to copy"
56 76 msgstr "Adicionar à cópia"
57 77  
58   -#: src/objects/application/actions/about.c:126
  78 +#: src/objects/application/actions/about.c:129
59 79 msgid "Apple version"
60 80 msgstr "Versão Apple"
61 81  
... ... @@ -63,11 +83,15 @@ msgstr &quot;Versão Apple&quot;
63 83 msgid "Application"
64 84 msgstr "Aplicação"
65 85  
66   -#: src/objects/application/actions/preferences.c:69 ui/application.xml:83
  86 +#: src/objects/window/header-settings.c:123
  87 +msgid "Application menu"
  88 +msgstr "Menu da aplicação"
  89 +
  90 +#: src/objects/application/actions/preferences.c:76 ui/application.xml:83
67 91 msgid "Application preferences"
68 92 msgstr "Preferências da aplicação"
69 93  
70   -#: src/objects/window/page.c:263
  94 +#: src/objects/window/page.c:264
71 95 msgid "Apply"
72 96 msgstr "Aplicar"
73 97  
... ... @@ -75,15 +99,15 @@ msgstr &quot;Aplicar&quot;
75 99 msgid "Auto-Reconnect"
76 100 msgstr "Reconectar automaticamente"
77 101  
78   -#: src/objects/toolbar/settings.c:114
  102 +#: src/objects/toolbar/settings.c:112 src/objects/settings/actionview.c:73
79 103 msgid "Available"
80 104 msgstr "Disponível"
81 105  
82   -#: src/objects/application/actions/about.c:130
  106 +#: src/objects/application/actions/about.c:132
83 107 msgid "Based on X3270 from"
84 108 msgstr "Baseado no X3270 por"
85 109  
86   -#: ui/window.xml:398 ui/application.xml:474
  110 +#: ui/window.xml:408 ui/application.xml:474
87 111 msgid "Blank Fill"
88 112 msgstr "Completar com espaços"
89 113  
... ... @@ -95,21 +119,17 @@ msgstr &quot;Cursor piscante&quot;
95 119 msgid "Bold"
96 120 msgstr "Negrito"
97 121  
98   -#: src/objects/application/actions/about.c:142
99   -msgid "Brazilian Public Software Portal"
100   -msgstr "Portal do Software Público Brasileiro"
  122 +#: src/objects/window/terminal.c:165
  123 +msgid "Can't load session file"
  124 +msgstr "Não foi possível carregar arquivo de sessão"
101 125  
102   -#: src/objects/window/terminal.c:197
  126 +#: src/objects/window/terminal.c:160
103 127 #, c-format
104   -msgid "Can't save file \"%s\""
105   -msgstr "Não foi possível salvar arquivo \"%s\""
106   -
107   -#: src/objects/window/terminal.c:202
108   -msgid "Can't save session file"
109   -msgstr "Não foi possível salvar arquivo de sessão"
  128 +msgid "Can't use \"%s\""
  129 +msgstr "Não posso usar %s"
110 130  
111   -#: src/objects/actions/save.c:65 src/objects/application/actions/open.c:49
112   -#: src/objects/window/page.c:264
  131 +#: src/objects/application/actions/open.c:49 src/objects/window/page.c:265
  132 +#: src/tools/entry.c:71
113 133 msgid "Cancel"
114 134 msgstr "_Cancelar"
115 135  
... ... @@ -117,7 +137,19 @@ msgstr &quot;_Cancelar&quot;
117 137 msgid "Change terminal colors"
118 138 msgstr "Mudar cores do terminal"
119 139  
120   -#: ui/window.xml:182 ui/window.xml:324 ui/application.xml:304
  140 +#: src/objects/application/actions/preferences.c:78
  141 +msgid "Change the application preferences"
  142 +msgstr "Modificar preferências da aplicação"
  143 +
  144 +#: src/objects/window/header-settings.c:98
  145 +msgid "Change the position of the title bar icons"
  146 +msgstr "Modificar posição dos ícones da barra de título"
  147 +
  148 +#: src/objects/window/actions/sessionproperties.c:47
  149 +msgid "Change the preferences for the active session"
  150 +msgstr "Modificar preferências da sessão ativa"
  151 +
  152 +#: ui/window.xml:192 ui/window.xml:334 ui/application.xml:304
121 153 msgid "Clear"
122 154 msgstr "Limpar"
123 155  
... ... @@ -134,8 +166,8 @@ msgstr &quot;Fecha todas as janelas e encerra a aplicação&quot;
134 166 msgid "Close the window"
135 167 msgstr "Fechar a janela"
136 168  
137   -#: src/objects/window/actions/close.c:60 ui/window.xml:270 ui/window.xml:458
138   -#: ui/window.xml:560 ui/application.xml:216
  169 +#: src/objects/window/actions/close.c:60 ui/window.xml:280 ui/window.xml:473
  170 +#: ui/window.xml:580 ui/application.xml:216
139 171 msgid "Close window"
140 172 msgstr "Fechar janela"
141 173  
... ... @@ -143,6 +175,10 @@ msgstr &quot;Fechar janela&quot;
143 175 msgid "Colors"
144 176 msgstr "Cores"
145 177  
  178 +#: src/objects/os/linux/savedesktopicon.c:101
  179 +msgid "Comment"
  180 +msgstr "Comentário"
  181 +
146 182 #: src/objects/window/actions/connect.c:59
147 183 msgid "Connect"
148 184 msgstr "Conectar"
... ... @@ -155,11 +191,15 @@ msgstr &quot;Conectar ao iniciar&quot;
155 191 msgid "Connect to host"
156 192 msgstr "Conectar ao servidor"
157 193  
158   -#: src/objects/window/window.c:702 src/objects/window/page.c:217
  194 +#: src/objects/window/window.c:753 src/objects/window/page.c:218
159 195 msgid "Connected to host"
160 196 msgstr "Conectado no servidor"
161 197  
162   -#: src/objects/application/actions/about.c:127
  198 +#: src/tools/entry.c:131
  199 +msgid "Continue"
  200 +msgstr "Continuar"
  201 +
  202 +#: src/objects/application/actions/about.c:130
163 203 msgid "Contributors"
164 204 msgstr "Contribuidores"
165 205  
... ... @@ -167,6 +207,14 @@ msgstr &quot;Contribuidores&quot;
167 207 msgid "Copy"
168 208 msgstr "Copiar"
169 209  
  210 +#: ui/window.xml:168
  211 +msgid "Copy as HTML"
  212 +msgstr "Copiar como HTML"
  213 +
  214 +#: ui/window.xml:173
  215 +msgid "Copy as image"
  216 +msgstr "Copiar como imagem"
  217 +
170 218 #: ui/window.xml:163 ui/application.xml:246
171 219 msgid "Copy as table"
172 220 msgstr "Copiar como tabela"
... ... @@ -175,11 +223,11 @@ msgstr &quot;Copiar como tabela&quot;
175 223 msgid "Copy as text"
176 224 msgstr "Copiar como texto"
177 225  
178   -#: src/objects/windows/savedesktopicon.c:79
179   -msgid "Create a desktop icon for the current session"
180   -msgstr "Criar ícone da área de trabalho para a sessão atual."
  226 +#: src/objects/os/linux/savedesktopicon.c:114
  227 +msgid "Create shortcut for the current session"
  228 +msgstr "Criar atalho para a sessão atual."
181 229  
182   -#: ui/window.xml:359 ui/application.xml:459
  230 +#: ui/window.xml:369 ui/application.xml:459
183 231 msgid "Cross hair cursor"
184 232 msgstr "Cursor mira"
185 233  
... ... @@ -195,28 +243,24 @@ msgstr &quot;Tela atual&quot;
195 243 msgid "Current session"
196 244 msgstr "Sessão atual"
197 245  
198   -#: ui/window.xml:173 ui/application.xml:256
  246 +#: ui/window.xml:183 ui/application.xml:256
199 247 msgid "Cut"
200 248 msgstr "Recortar"
201 249  
202   -#: ui/window.xml:192 ui/window.xml:334 ui/application.xml:314
  250 +#: ui/window.xml:202 ui/window.xml:344 ui/application.xml:314
203 251 msgid "Delete Field"
204 252 msgstr "Apagar campo"
205 253  
206   -#: ui/window.xml:93 ui/application.xml:158
207   -msgid "Desktop icon"
208   -msgstr "Ícone da área de trabalho"
209   -
210   -#: ui/window.xml:265 ui/window.xml:453
  254 +#: ui/window.xml:275 ui/window.xml:468
211 255 msgid "Disconnect"
212 256 msgstr "Desconectar"
213 257  
214   -#: src/objects/window/window.c:702 src/objects/window/window.c:729
215   -#: src/objects/window/page.c:206
  258 +#: src/objects/window/window.c:753 src/objects/window/window.c:780
  259 +#: src/objects/window/page.c:207
216 260 msgid "Disconnected from host"
217 261 msgstr "Desconectado do servidor"
218 262  
219   -#: ui/window.xml:381 ui/window.xml:492 ui/application.xml:524
  263 +#: ui/window.xml:391 ui/window.xml:507 ui/application.xml:524
220 264 msgid "Dynamic font spacing"
221 265 msgstr "Espaçamento dinâmico"
222 266  
... ... @@ -240,15 +284,19 @@ msgstr &quot;Largura do elemento em colunas&quot;
240 284 msgid "Enabled"
241 285 msgstr "Habilitado"
242 286  
243   -#: ui/window.xml:187 ui/window.xml:329 ui/application.xml:309
  287 +#: src/objects/settings/actionview.c:78
  288 +msgid "End"
  289 +msgstr "Final"
  290 +
  291 +#: ui/window.xml:197 ui/window.xml:339 ui/application.xml:309
244 292 msgid "Erase input"
245 293 msgstr "Apagar campos"
246 294  
247   -#: ui/window.xml:197 ui/window.xml:339 ui/application.xml:319
  295 +#: ui/window.xml:207 ui/window.xml:349 ui/application.xml:319
248 296 msgid "Erase to end of field"
249 297 msgstr "Apagar até o final do campo"
250 298  
251   -#: ui/window.xml:202 ui/window.xml:344 ui/application.xml:324
  299 +#: ui/window.xml:212 ui/window.xml:354 ui/application.xml:324
252 300 msgid "Erase to end of line"
253 301 msgstr "Apagar até o final da linha"
254 302  
... ... @@ -256,15 +304,11 @@ msgstr &quot;Apagar até o final da linha&quot;
256 304 msgid "Field attributes"
257 305 msgstr "Mostra atributos de campo"
258 306  
259   -#: src/objects/windows/savedesktopicon.c:62
260   -msgid "File name"
261   -msgstr "Nome do arquivo"
262   -
263 307 #: ui/application.xml:454
264 308 msgid "Full Screen"
265 309 msgstr "Tela cheia"
266 310  
267   -#: ui/window.xml:236 ui/window.xml:407 ui/window.xml:497
  311 +#: ui/window.xml:246 ui/window.xml:417 ui/window.xml:512
268 312 msgid "Full screen"
269 313 msgstr "Tela cheia"
270 314  
... ... @@ -272,6 +316,10 @@ msgstr &quot;Tela cheia&quot;
272 316 msgid "Function bar"
273 317 msgstr "Barra de funções"
274 318  
  319 +#: src/objects/os/linux/savedesktopicon.c:94
  320 +msgid "Generic name"
  321 +msgstr "Nome genérico"
  322 +
275 323 #: ui/application.xml:36 ui/application.xml:534
276 324 msgid "Help"
277 325 msgstr "Ajuda"
... ... @@ -280,11 +328,11 @@ msgstr &quot;Ajuda&quot;
280 328 msgid "Host properties"
281 329 msgstr "Propriedades do Servidor"
282 330  
283   -#: src/objects/window/window.c:469
  331 +#: src/objects/window/window.c:552 src/objects/os/linux/savedesktopicon.c:102
284 332 msgid "IBM 3270 Terminal emulator"
285 333 msgstr "Emulador 3270"
286 334  
287   -#: src/objects/actions/view.c:89
  335 +#: src/objects/actions/view.c:90
288 336 msgid "Icon"
289 337 msgstr "Ícone"
290 338  
... ... @@ -292,19 +340,27 @@ msgstr &quot;Ícone&quot;
292 340 msgid "Icon Name"
293 341 msgstr "Nome do ícone"
294 342  
295   -#: src/objects/toolbar/settings.c:50
  343 +#: src/objects/toolbar/settings.c:54
296 344 msgid "Icon Size"
297 345 msgstr "Tamanho do ícone"
298 346  
299   -#: src/objects/toolbar/toolbar.c:262
  347 +#: src/objects/toolbar/settings.c:61
  348 +msgid "Icon Style"
  349 +msgstr "Estilo do ícone"
  350 +
  351 +#: src/objects/toolbar/models.c:52
300 352 msgid "Icon _size"
301 353 msgstr "_Tamanho do ícone"
302 354  
303   -#: src/objects/toolbar/toolbar.c:84
  355 +#: src/objects/toolbar/models.c:108
  356 +msgid "Icon type"
  357 +msgstr "Tipo do ícone"
  358 +
  359 +#: src/objects/toolbar/models.c:97
304 360 msgid "Icons & text"
305 361 msgstr "Ícones e texto"
306 362  
307   -#: src/objects/toolbar/toolbar.c:74
  363 +#: src/objects/toolbar/models.c:87
308 364 msgid "Icons only"
309 365 msgstr "Apenas ícones"
310 366  
... ... @@ -312,7 +368,7 @@ msgstr &quot;Apenas ícones&quot;
312 368 msgid "If the action can be activated"
313 369 msgstr "Se a ação pode ser ativada"
314 370  
315   -#: ui/window.xml:469
  371 +#: ui/window.xml:484
316 372 msgid "Insert"
317 373 msgstr "Inserção"
318 374  
... ... @@ -320,7 +376,15 @@ msgstr &quot;Inserção&quot;
320 376 msgid "Invalid or unknown property type"
321 377 msgstr "Tipo da propriedade é inválido ou desconhecido"
322 378  
323   -#: src/objects/toolbar/settings.c:108
  379 +#: src/objects/settings/actionview.c:79
  380 +msgid "Items packed from the end to the start"
  381 +msgstr "Itens empacotados do final para o início"
  382 +
  383 +#: src/objects/settings/actionview.c:69
  384 +msgid "Items packed from the start to the end"
  385 +msgstr "Itens empacotados do início para o final"
  386 +
  387 +#: src/objects/toolbar/settings.c:106
324 388 msgid "Itens"
325 389 msgstr "Itens"
326 390  
... ... @@ -348,22 +412,26 @@ msgstr &quot;Largura do painel em colunas&quot;
348 412 msgid "Keypads"
349 413 msgstr "Painéis"
350 414  
351   -#: src/objects/actions/view.c:98
  415 +#: src/objects/application/actions/about.c:140
  416 +msgid "LICENSE"
  417 +msgstr "LICENCA"
  418 +
  419 +#: src/objects/actions/view.c:99
352 420 msgid "Label"
353 421 msgstr "Etiqueta"
354 422  
355   -#: src/objects/toolbar/toolbar.c:58
  423 +#: src/objects/toolbar/models.c:66
356 424 msgid "Large"
357 425 msgstr "Grande"
358 426  
359   -#: src/objects/windows/savedesktopicon.c:67
360   -msgid "Launcher name"
361   -msgstr "Nome do lançador"
362   -
363   -#: src/objects/toolbar/settings.c:207
  427 +#: src/objects/toolbar/settings.c:176
364 428 msgid "Layout"
365 429 msgstr "Formato"
366 430  
  431 +#: src/objects/settings/actionview.c:74
  432 +msgid "List of the available and unpacked actions"
  433 +msgstr "Lista de ações disponíveis ainda não empacotadas"
  434 +
367 435 #: ui/application.xml:71
368 436 msgid "Main Menu"
369 437 msgstr "Menu principal"
... ... @@ -372,11 +440,11 @@ msgstr &quot;Menu principal&quot;
372 440 msgid "Main Toolbar"
373 441 msgstr "Barra de ferramentas"
374 442  
375   -#: ui/window.xml:540
  443 +#: ui/window.xml:555
376 444 msgid "Main menu"
377 445 msgstr "Menu principal"
378 446  
379   -#: src/objects/application/actions/about.c:125
  447 +#: src/objects/application/actions/about.c:128
380 448 msgid "Maintainers"
381 449 msgstr "Mantenedores"
382 450  
... ... @@ -384,23 +452,23 @@ msgstr &quot;Mantenedores&quot;
384 452 msgid "Menu"
385 453 msgstr "Menu"
386 454  
387   -#: ui/window.xml:506 ui/application.xml:403
  455 +#: ui/window.xml:521 ui/application.xml:403
388 456 msgid "Model 2 - 80x24"
389 457 msgstr "Modelo 2 - 80x24"
390 458  
391   -#: ui/window.xml:511 ui/application.xml:408
  459 +#: ui/window.xml:526 ui/application.xml:408
392 460 msgid "Model 3 - 80x32"
393 461 msgstr "Modelo 3 - 80x32"
394 462  
395   -#: ui/window.xml:516 ui/application.xml:413
  463 +#: ui/window.xml:531 ui/application.xml:413
396 464 msgid "Model 4 - 80x43"
397 465 msgstr "Modelo 4 - 80x43"
398 466  
399   -#: ui/window.xml:521 ui/application.xml:418
  467 +#: ui/window.xml:536 ui/application.xml:418
400 468 msgid "Model 5 - 132x27"
401 469 msgstr "Modelo 5 - 132x27"
402 470  
403   -#: ui/window.xml:376 ui/application.xml:444
  471 +#: ui/window.xml:386 ui/application.xml:444
404 472 msgid "Monocase"
405 473 msgstr "Só Maiúsculas"
406 474  
... ... @@ -408,7 +476,7 @@ msgstr &quot;Só Maiúsculas&quot;
408 476 msgid "Network keep alive"
409 477 msgstr "Network keep alive"
410 478  
411   -#: src/objects/window/page.c:274
  479 +#: src/objects/window/page.c:275
412 480 msgid "New session name"
413 481 msgstr "Novo nome de sessão"
414 482  
... ... @@ -456,7 +524,7 @@ msgstr &quot;Abrir sessão em nova aba&quot;
456 524 msgid "Open session in New window"
457 525 msgstr "Abrir sessão em nova janela"
458 526  
459   -#: ui/window.xml:212 ui/window.xml:354 ui/window.xml:489 ui/application.xml:431
  527 +#: ui/window.xml:222 ui/window.xml:364 ui/window.xml:504 ui/application.xml:431
460 528 msgid "Options"
461 529 msgstr "Opções"
462 530  
... ... @@ -464,22 +532,26 @@ msgstr &quot;Opções&quot;
464 532 msgid "Parameter Type"
465 533 msgstr "Tipo de parâmetro"
466 534  
467   -#: ui/window.xml:286 ui/application.xml:261
  535 +#: ui/window.xml:296 ui/application.xml:261
468 536 msgid "Paste from clipboard"
469 537 msgstr "Colar da área de transferência"
470 538  
471   -#: ui/window.xml:296 ui/application.xml:271
  539 +#: ui/window.xml:306 ui/application.xml:271
472 540 msgid "Paste from text file"
473 541 msgstr "Colar de um arquivo texto"
474 542  
475   -#: ui/window.xml:291 ui/application.xml:266
  543 +#: ui/window.xml:301 ui/application.xml:266
476 544 msgid "Paste next"
477 545 msgstr "Colar próximo"
478 546  
479   -#: ui/window.xml:393 ui/application.xml:469
  547 +#: ui/window.xml:403 ui/application.xml:469
480 548 msgid "Paste with left margin"
481 549 msgstr "Colar com margem esquerda"
482 550  
  551 +#: src/objects/os/linux/savedesktopicon.c:71
  552 +msgid "Path for the new shortcut"
  553 +msgstr "Caminho para o novo atalho"
  554 +
483 555 #: ui/window.xml:129
484 556 msgid "Preferences"
485 557 msgstr "Preferências"
... ... @@ -488,11 +560,11 @@ msgstr &quot;Preferências&quot;
488 560 msgid "Print"
489 561 msgstr "Imprimir"
490 562  
491   -#: ui/window.xml:439
  563 +#: ui/window.xml:454
492 564 msgid "Print screen"
493 565 msgstr "Imrpimir o conteúdo da tela"
494 566  
495   -#: ui/window.xml:252
  567 +#: ui/window.xml:262
496 568 msgid "Print selected"
497 569 msgstr "Imprimir seleção"
498 570  
... ... @@ -505,15 +577,15 @@ msgstr &quot;Propriedade \&quot;%s\&quot; é inválida para este objeto&quot;
505 577 msgid "Quit"
506 578 msgstr "Sair"
507 579  
508   -#: src/objects/window/page.c:261
  580 +#: src/objects/window/page.c:262
509 581 msgid "Rename Session"
510 582 msgstr "Renomear sessão"
511 583  
512   -#: ui/window.xml:315 ui/application.xml:295
  584 +#: ui/window.xml:325 ui/application.xml:295
513 585 msgid "Reselect"
514 586 msgstr "Reselecionar"
515 587  
516   -#: ui/window.xml:364 ui/application.xml:464
  588 +#: ui/window.xml:374 ui/application.xml:464
517 589 msgid "Resize on alternate screen"
518 590 msgstr "Mudar tamanho do terminal em tela alternativa"
519 591  
... ... @@ -521,55 +593,59 @@ msgstr &quot;Mudar tamanho do terminal em tela alternativa&quot;
521 593 msgid "Right keypad"
522 594 msgstr "Painel direito"
523 595  
524   -#: src/objects/toolbar/toolbar.c:286
525   -msgid "S_tyle"
526   -msgstr "E_stilo"
527   -
528   -#: src/objects/actions/save.c:64 ui/window.xml:69 ui/application.xml:134
  596 +#: ui/window.xml:69 ui/application.xml:134
529 597 msgid "Save"
530 598 msgstr "Salvar"
531 599  
532   -#: src/objects/actions/save.c:49
533   -msgid "Save As"
534   -msgstr "Salvar Como"
535   -
536   -#: src/objects/windows/savedesktopicon.c:78
537   -msgid "Save desktop icon"
538   -msgstr "Salvar ícone da área de trabalho"
  600 +#: src/objects/actions/save.c:77
  601 +msgid "Save current session preferences to file"
  602 +msgstr "Salvar preferências da sessão para arquivo"
539 603  
540   -#: ui/window.xml:434
  604 +#: ui/window.xml:449
541 605 msgid "Save screen"
542 606 msgstr "Salvar tela"
543 607  
544   -#: ui/window.xml:247
  608 +#: ui/window.xml:257
545 609 msgid "Save selected"
546 610 msgstr "Salvar seleção"
547 611  
548   -#: src/objects/actions/save.c:51
549   -msgid "Save session properties"
550   -msgstr "Salvar propriedades da sessão"
  612 +#: src/objects/actions/save.c:75 src/objects/actions/save.c:153
  613 +msgid "Save session preferences"
  614 +msgstr "Salvar preferências da sessão"
  615 +
  616 +#: src/objects/os/linux/savedesktopicon.c:113
  617 +msgid "Save session shortcut"
  618 +msgstr "Salvar atalho para a sessão"
551 619  
552   -#: ui/window.xml:503 ui/application.xml:400
  620 +#: src/objects/os/linux/savedesktopicon.c:264
  621 +msgid "Save to session filename"
  622 +msgstr "Salvar para arquivo de sessão"
  623 +
  624 +#: src/objects/os/linux/savedesktopicon.c:236
  625 +msgid "Save to shortcut file"
  626 +msgstr "Salvar para atalho"
  627 +
  628 +#: ui/window.xml:518 ui/application.xml:400
553 629 msgid "Screen size"
554 630 msgstr "Tamanho da tela"
555 631  
556   -#: ui/window.xml:310 ui/application.xml:285
  632 +#: ui/window.xml:320 ui/application.xml:285
557 633 msgid "Select Field"
558 634 msgstr "Selecionar campo"
559 635  
560   -#: ui/window.xml:305 ui/application.xml:280
  636 +#: ui/window.xml:315 ui/application.xml:280
561 637 msgid "Select all"
562 638 msgstr "Selecionar tudo"
563 639  
564   -#: ui/window.xml:217 ui/application.xml:479
  640 +#: ui/window.xml:227 ui/application.xml:479
565 641 msgid "Select by rectangles"
566 642 msgstr "Seleção retangular"
567 643  
568   -#: src/objects/toolbar/settings.c:108
  644 +#: src/objects/toolbar/settings.c:106
569 645 msgid "Select the toolbar itens"
570 646 msgstr "Selecione itens da barra de ferramentas"
571 647  
572   -#: src/objects/toolbar/settings.c:113
  648 +#: src/objects/toolbar/settings.c:111
573 649 msgid "Selected"
574 650 msgstr "Selecionado"
575 651  
... ... @@ -582,12 +658,12 @@ msgstr &quot;Área selecionada&quot;
582 658 msgid "Send/Receive"
583 659 msgstr "Enviar/Receber"
584 660  
585   -#: src/objects/window/actions/filetransfer.c:46 ui/window.xml:444
  661 +#: src/objects/window/actions/filetransfer.c:46 ui/window.xml:459
586 662 #: ui/application.xml:195
587 663 msgid "Send/Receive files"
588 664 msgstr "Enviar/Receber arquivos"
589 665  
590   -#: src/objects/toolbar/settings.c:266 src/objects/toolbar/settings.c:276
  666 +#: src/objects/toolbar/settings.c:234 src/objects/toolbar/settings.c:244
591 667 msgid "Separator"
592 668 msgstr "Separador"
593 669  
... ... @@ -595,10 +671,14 @@ msgstr &quot;Separador&quot;
595 671 msgid "Session"
596 672 msgstr "Sessão"
597 673  
598   -#: ui/application.xml:76
  674 +#: ui/window.xml:440 ui/window.xml:560 ui/application.xml:76
599 675 msgid "Session Trace"
600 676 msgstr "Trace da sessão"
601 677  
  678 +#: src/objects/actions/save.c:63 src/objects/os/linux/savedesktopicon.c:85
  679 +msgid "Session file"
  680 +msgstr "Arquivo de sessão"
  681 +
602 682 #: ui/window.xml:61 ui/application.xml:126
603 683 msgid "Session in New Tab"
604 684 msgstr "Sessão em nova aba"
... ... @@ -607,12 +687,16 @@ msgstr &quot;Sessão em nova aba&quot;
607 687 msgid "Session in new window"
608 688 msgstr "Sessão em nova janela"
609 689  
610   -#: src/objects/window/actions/sessionproperties.c:45 ui/window.xml:98
611   -#: ui/window.xml:554 ui/application.xml:163
612   -msgid "Session properties"
613   -msgstr "Propriedades da sessão"
  690 +#: src/objects/actions/save.c:56 src/objects/os/linux/savedesktopicon.c:77
  691 +msgid "Session name"
  692 +msgstr "Nome da sessão"
614 693  
615   -#: src/objects/application/application.c:221
  694 +#: src/objects/window/actions/sessionproperties.c:46 ui/window.xml:98
  695 +#: ui/window.xml:574 ui/application.xml:163
  696 +msgid "Session preferences"
  697 +msgstr "Preferências da sessão"
  698 +
  699 +#: src/objects/application/application.c:219
616 700 msgid "Set the user-interface type"
617 701 msgstr "Define o tipo de interface do usuário"
618 702  
... ... @@ -620,34 +704,58 @@ msgstr &quot;Define o tipo de interface do usuário&quot;
620 704 msgid "Settings"
621 705 msgstr "Configurações"
622 706  
623   -#: src/objects/toolbar/settings.c:207
  707 +#: src/objects/toolbar/settings.c:176
624 708 msgid "Setup the toolbar layout"
625 709 msgstr "Configura formato da barra de ferramentas"
626 710  
627   -#: src/objects/toolbar/settings.c:90
  711 +#: src/objects/window/header-settings.c:87
  712 +msgid "Setup title bar"
  713 +msgstr "Configurar barra de título"
  714 +
  715 +#: src/objects/toolbar/toolbar.c:214 src/objects/toolbar/settings.c:88
628 716 msgid "Setup toolbar"
629 717 msgstr "Configurar barra de ferramentas"
630 718  
  719 +#: src/objects/os/linux/savedesktopicon.c:70
  720 +msgid "Shortcut file"
  721 +msgstr "Arquivo de atalho"
  722 +
  723 +#: ui/window.xml:93 ui/application.xml:158
  724 +msgid "Shortcut for this session"
  725 +msgstr "Atalho para essa sessão"
  726 +
  727 +#: src/objects/os/linux/savedesktopicon.c:63
  728 +msgid "Shortcut name"
  729 +msgstr "Nome do atalho"
  730 +
631 731 #: ui/application.xml:494
632 732 msgid "Show Underline"
633 733 msgstr "Mostrar sublinhado"
634 734  
635   -#: ui/window.xml:231
  735 +#: ui/window.xml:241
636 736 msgid "Show menu"
637 737 msgstr "Mostrar menu"
638 738  
639   -#: ui/window.xml:226
  739 +#: ui/window.xml:236
640 740 msgid "Show toolbar"
641 741 msgstr "Mostrar barra de ferramentas"
642 742  
643   -#: src/objects/toolbar/toolbar.c:53
  743 +#: src/objects/toolbar/models.c:61
644 744 msgid "Small"
645 745 msgstr "Pequeno"
646 746  
647   -#: ui/window.xml:388 ui/application.xml:504
  747 +#: ui/window.xml:398 ui/application.xml:504
648 748 msgid "Smart paste"
649 749 msgstr "Colar inteligente"
650 750  
  751 +#: src/objects/os/linux/savedesktopicon.c:239
  752 +msgid "Standard desktop files"
  753 +msgstr "Arquivo de atalho padrão"
  754 +
  755 +#: src/objects/settings/actionview.c:68
  756 +msgid "Start"
  757 +msgstr "Inicio"
  758 +
651 759 #: src/objects/actions/abstract.c:152
652 760 msgid "State"
653 761 msgstr "Estado"
... ... @@ -656,11 +764,12 @@ msgstr &quot;Estado&quot;
656 764 msgid "State Type"
657 765 msgstr "Tipo do estado"
658 766  
659   -#: src/objects/toolbar/settings.c:55
660   -msgid "Style"
661   -msgstr "Estilo"
  767 +#: src/objects/toolbar/models.c:115
  768 +msgid "Symbolic"
  769 +msgstr "Simbólico"
662 770  
663   -#: src/objects/toolbar/toolbar.c:47 src/objects/toolbar/toolbar.c:69
  771 +#: src/objects/toolbar/models.c:55 src/objects/toolbar/models.c:82
  772 +#: src/objects/toolbar/models.c:111
664 773 msgid "System default"
665 774 msgstr "Padrão do sistema"
666 775  
... ... @@ -676,7 +785,7 @@ msgstr &quot;Aba com a sessão padrão&quot;
676 785 msgid "Terminal font"
677 786 msgstr "Fonte do terminal"
678 787  
679   -#: src/objects/toolbar/toolbar.c:79
  788 +#: src/objects/toolbar/models.c:92
680 789 msgid "Text only"
681 790 msgstr "Apenas texto"
682 791  
... ... @@ -696,6 +805,14 @@ msgstr &quot;A dica da ação&quot;
696 805 msgid "The code of the User interface type"
697 806 msgstr "Código identificando o tipo de interface do usuário"
698 807  
  808 +#: src/objects/actions/save.c:64
  809 +msgid "The file to save the current session preferences"
  810 +msgstr "O arquivo com as preferências da sessão atual"
  811 +
  812 +#: src/objects/os/linux/savedesktopicon.c:86
  813 +msgid "The file with the session preferences for this shortcut"
  814 +msgstr "O arquivo com as preferências da sessão para esse atalho"
  815 +
699 816 #: src/objects/actions/abstract.c:110
700 817 msgid "The label for the action"
701 818 msgstr "A etiqueta da ação"
... ... @@ -704,11 +821,11 @@ msgstr &quot;A etiqueta da ação&quot;
704 821 msgid "The name of associated action"
705 822 msgstr "Nome da ação associada"
706 823  
707   -#: src/objects/window/window.c:164
  824 +#: src/objects/window/window.c:185
708 825 msgid "The name of the actions in the header bar"
709 826 msgstr "O nome das ações na barra de título"
710 827  
711   -#: src/objects/toolbar/toolbar.c:136
  828 +#: src/objects/toolbar/toolbar.c:98
712 829 msgid "The name of the actions in the toolbar"
713 830 msgstr "O nome das ações na barra de ferramentas"
714 831  
... ... @@ -732,15 +849,25 @@ msgstr &quot;O nome usado para ativar a ação&quot;
732 849 msgid "The position of the keypad"
733 850 msgstr "A posição do painel"
734 851  
  852 +#: src/objects/actions/save.c:57 src/objects/os/linux/savedesktopicon.c:79
  853 +msgid "The session name used in the window/tab title (empty for default)"
  854 +msgstr ""
  855 +"O nome da sessão usada no título da janela/aba. Vazio para usar o valor "
  856 +"padrão"
  857 +
735 858 #: src/objects/actions/abstract.c:153
736 859 msgid "The state the action is in"
737 860 msgstr "O estado em que a ação está"
738 861  
739   -#: src/objects/toolbar/toolbar.c:147
  862 +#: src/objects/toolbar/toolbar.c:109
740 863 msgid "The toolbar icon size"
741 864 msgstr "Tamanho dos ícones na barra de ferramentas"
742 865  
743   -#: src/objects/toolbar/toolbar.c:160
  866 +#: src/objects/toolbar/toolbar.c:135
  867 +msgid "The toolbar icon type"
  868 +msgstr "Tipo dos ícones na barra de ferramentas"
  869 +
  870 +#: src/objects/toolbar/toolbar.c:122
744 871 msgid "The toolbar style"
745 872 msgstr "Estilo da barra de ferramentas"
746 873  
... ... @@ -756,12 +883,28 @@ msgstr &quot;The type of GVariant passed to activate()&quot;
756 883 msgid "The type of the state kept by the action"
757 884 msgstr "O tipo do estado mantido pela ação"
758 885  
759   -#: src/objects/toolbar/settings.c:89 ui/window.xml:420 ui/window.xml:535
  886 +#: src/objects/window/header-settings.c:86
  887 +msgid "Title bar"
  888 +msgstr "Barra de título"
  889 +
  890 +#: src/objects/window/header-settings.c:98
  891 +msgid "Title bar actions"
  892 +msgstr "Ações da barra de título"
  893 +
  894 +#: src/objects/toolbar/settings.c:87 ui/window.xml:430 ui/window.xml:550
760 895 #: ui/application.xml:342
761 896 msgid "Toolbar"
762 897 msgstr "Barra de ferramentas"
763 898  
764   -#: ui/window.xml:425
  899 +#: src/objects/toolbar/settings.c:68
  900 +msgid "Toolbar Style"
  901 +msgstr "Estilo da barra de ferramentas"
  902 +
  903 +#: src/objects/toolbar/models.c:79
  904 +msgid "Toolbar s_tyle"
  905 +msgstr "Est_ilo da barra de ferramentas"
  906 +
  907 +#: ui/window.xml:435
765 908 msgid "Top menu"
766 909 msgstr "Menu principal"
767 910  
... ... @@ -769,7 +912,7 @@ msgstr &quot;Menu principal&quot;
769 912 msgid "Trace"
770 913 msgstr "Trace"
771 914  
772   -#: ui/window.xml:474 ui/application.xml:449
  915 +#: ui/window.xml:489 ui/application.xml:449
773 916 msgid "Track Cursor"
774 917 msgstr "Mostrar posição do cursor"
775 918  
... ... @@ -777,7 +920,7 @@ msgstr &quot;Mostrar posição do cursor&quot;
777 920 msgid "UI Type"
778 921 msgstr "Interface de usuário"
779 922  
780   -#: ui/window.xml:257 ui/application.xml:290
  923 +#: ui/window.xml:267 ui/application.xml:290
781 924 msgid "Unselect"
782 925 msgstr "Remover seleção"
783 926  
... ... @@ -785,34 +928,38 @@ msgstr &quot;Remover seleção&quot;
785 928 msgid "Use +/- for field navigation"
786 929 msgstr "Usar teclas +/- para navegar por campos"
787 930  
788   -#: src/objects/application/actions/about.c:86
789   -#: src/objects/application/actions/about.c:88
  931 +#: src/objects/application/actions/about.c:70
790 932 #, c-format
791 933 msgid "Version %s-%s"
792 934 msgstr "Versão %s-%s"
793 935  
794   -#: src/objects/window/header.c:66 ui/window.xml:417 ui/window.xml:532
  936 +#: src/objects/window/header.c:66 ui/window.xml:427 ui/window.xml:547
795 937 #: ui/application.xml:63
796 938 msgid "View"
797 939 msgstr "Exibir"
798 940  
  941 +#: src/objects/application/actions/about.c:163
  942 +msgid "View this project on github"
  943 +msgstr "Portal do Software Público Brasileiro"
  944 +
799 945 #: ui/window.xml:40 ui/application.xml:105
800 946 msgid "Window with default session"
801 947 msgstr "Janela com sessão padrão"
802 948  
803   -#: src/objects/settings/dialog.c:84
  949 +#: src/objects/settings/dialog.c:79
804 950 msgid "_Apply"
805 951 msgstr "_Aplicar"
806 952  
807   -#: src/objects/settings/dialog.c:83 src/objects/windows/savedesktopicon.c:104
  953 +#: src/objects/actions/save.c:102 src/objects/settings/dialog.c:78
  954 +#: src/objects/os/linux/savedesktopicon.c:174
808 955 msgid "_Cancel"
809 956 msgstr "_Cancelar"
810 957  
811   -#: src/objects/window/page.c:394
  958 +#: src/objects/window/page.c:371
812 959 msgid "_Close session"
813 960 msgstr "_Fechar sessão"
814 961  
815   -#: ui/window.xml:549 ui/application.xml:368
  962 +#: ui/window.xml:569 ui/application.xml:368
816 963 msgid "_Connect"
817 964 msgstr "_Conectar"
818 965  
... ... @@ -820,7 +967,7 @@ msgstr &quot;_Conectar&quot;
820 967 msgid "_Disconnect"
821 968 msgstr "_Desconectar"
822 969  
823   -#: ui/window.xml:148 ui/window.xml:281 ui/application.xml:231
  970 +#: ui/window.xml:148 ui/window.xml:291 ui/application.xml:231
824 971 msgid "_Edit"
825 972 msgstr "_Editar"
826 973  
... ... @@ -840,15 +987,15 @@ msgstr &quot;_Nova&quot;
840 987 msgid "_Open"
841 988 msgstr "_Abrir"
842 989  
843   -#: src/objects/toolbar/toolbar.c:308
844   -msgid "_Properties"
845   -msgstr "_Propriedades"
  990 +#: src/objects/toolbar/toolbar.c:236
  991 +msgid "_Preferences"
  992 +msgstr "_Preferências"
846 993  
847   -#: src/objects/window/page.c:388
  994 +#: src/objects/window/page.c:365
848 995 msgid "_Rename session"
849 996 msgstr "Renomear sessão"
850 997  
851   -#: src/objects/windows/savedesktopicon.c:105
  998 +#: src/objects/actions/save.c:103 src/objects/os/linux/savedesktopicon.c:175
852 999 msgid "_Save"
853 1000 msgstr "_Salvar"
854 1001  
... ... @@ -856,7 +1003,11 @@ msgstr &quot;_Salvar&quot;
856 1003 msgid "_View"
857 1004 msgstr "_Exibir"
858 1005  
859   -#: src/objects/application/actions/about.c:145
  1006 +#: src/objects/application/actions/about.c:162
  1007 +msgid "https://github.com/PerryWerneck/pw3270"
  1008 +msgstr "https://portal.softwarepublico.gov.br/social/pw3270/"
  1009 +
  1010 +#: src/objects/application/actions/about.c:165
860 1011 msgid "translator-credits"
861 1012 msgstr "translator-credits"
862 1013  
... ... @@ -1165,6 +1316,10 @@ msgstr &quot;translator-credits&quot;
1165 1316 #~ msgid "Blue"
1166 1317 #~ msgstr "Azul"
1167 1318  
  1319 +#~ msgctxt "ProjectURLTitle"
  1320 +#~ msgid "Brazilian Public Software Portal"
  1321 +#~ msgstr "Portal do Software Público Brasileiro"
  1322 +
1168 1323 #~ msgid "Break"
1169 1324 #~ msgstr "Break"
1170 1325  
... ... @@ -1287,7 +1442,7 @@ msgstr &quot;translator-credits&quot;
1287 1442 #~ msgid "Can't load plugin %s"
1288 1443 #~ msgstr "Não foi possível carregar plugin %s"
1289 1444  
1290   -#~ msgid "Can't open %s"
  1445 +#~ msgid "Can't open \"%s\""
1291 1446 #~ msgstr "Não foi possível abrir %s"
1292 1447  
1293 1448 #~ msgid "Can't open CRL File"
... ... @@ -1335,9 +1490,6 @@ msgstr &quot;translator-credits&quot;
1335 1490 #~ msgid "Can't save \"%s\": %s"
1336 1491 #~ msgstr "Não foi possível salvar %s: %s"
1337 1492  
1338   -#~ msgid "Can't save %s"
1339   -#~ msgstr "Não foi possível salvar arquivo %s"
1340   -
1341 1493 #~ msgid ""
1342 1494 #~ "Can't save copy to file\n"
1343 1495 #~ "%s"
... ... @@ -1345,6 +1497,9 @@ msgstr &quot;translator-credits&quot;
1345 1497 #~ "Não foi possível salvar cópia para o arquivo\n"
1346 1498 #~ "%s"
1347 1499  
  1500 +#~ msgid "Can't save file \"%s\""
  1501 +#~ msgstr "Não foi possível salvar arquivo \"%s\""
  1502 +
1348 1503 #~ msgid ""
1349 1504 #~ "Can't save screen to file\n"
1350 1505 #~ "%s"
... ... @@ -1508,9 +1663,6 @@ msgstr &quot;translator-credits&quot;
1508 1663 #~ msgid "Command to execute"
1509 1664 #~ msgstr "Comando a executar"
1510 1665  
1511   -#~ msgid "Comment"
1512   -#~ msgstr "Comentário"
1513   -
1514 1666 #~ msgid "Complete"
1515 1667 #~ msgstr "Completo"
1516 1668  
... ... @@ -1532,9 +1684,6 @@ msgstr &quot;translator-credits&quot;
1532 1684 #~ msgid "Copiar tudo"
1533 1685 #~ msgstr "Copiar tudo"
1534 1686  
1535   -#~ msgid "Copy as HTML"
1536   -#~ msgstr "Copiar como HTML"
1537   -
1538 1687 #~ msgid "Creates a file with fixed-length records."
1539 1688 #~ msgstr "Cria arquivo com registros de tamanho fixo."
1540 1689  
... ... @@ -1620,9 +1769,15 @@ msgstr &quot;translator-credits&quot;
1620 1769 #~ msgid "Default host URL"
1621 1770 #~ msgstr "URL parão para acesso ao host"
1622 1771  
  1772 +#~ msgid "Description"
  1773 +#~ msgstr "Descrição"
  1774 +
1623 1775 #~ msgid "Description of the current security state"
1624 1776 #~ msgstr "Descrição do estado de segurança atual"
1625 1777  
  1778 +#~ msgid "Desktop icon"
  1779 +#~ msgstr "Ícone da área de trabalho"
  1780 +
1626 1781 #~ msgid "Device type rejected"
1627 1782 #~ msgstr "Tipo de dispositivo rejeitado"
1628 1783  
... ... @@ -1766,6 +1921,9 @@ msgstr &quot;translator-credits&quot;
1766 1921 #~ msgid "File _Format"
1767 1922 #~ msgstr "_Formato do arquivo"
1768 1923  
  1924 +#~ msgid "File name"
  1925 +#~ msgstr "Nome do arquivo"
  1926 +
1769 1927 #~ msgid "File transfer complete"
1770 1928 #~ msgstr "Transferência completa"
1771 1929  
... ... @@ -1836,9 +1994,6 @@ msgstr &quot;translator-credits&quot;
1836 1994 #~ msgid "GTK Version mismatch"
1837 1995 #~ msgstr "Divergência de versão GTK"
1838 1996  
1839   -#~ msgid "Generic name"
1840   -#~ msgstr "Nome genérico"
1841   -
1842 1997 #~ msgid "Get transfer queue from an external XML file"
1843 1998 #~ msgstr "Obtém a fila de transferência de um arquivo XML externo"
1844 1999  
... ... @@ -2142,6 +2297,12 @@ msgstr &quot;translator-credits&quot;
2142 2297 #~ msgid "Latest program message"
2143 2298 #~ msgstr "Última mensagem de programa"
2144 2299  
  2300 +#~ msgid "Launcher name"
  2301 +#~ msgstr "Nome do lançador"
  2302 +
  2303 +#~ msgid "Left"
  2304 +#~ msgstr "Esquerda"
  2305 +
2145 2306 #~ msgid "Load"
2146 2307 #~ msgstr "Load"
2147 2308  
... ... @@ -2459,6 +2620,10 @@ msgstr &quot;translator-credits&quot;
2459 2620 #~ msgid "Port or service name (empty for \"telnet\")."
2460 2621 #~ msgstr "Nº da porta ou nome do serviço (em branco para \"telnet\")."
2461 2622  
  2623 +#~ msgctxt "PrjLabel"
  2624 +#~ msgid "Portal do Software Público Brasileiro"
  2625 +#~ msgstr "https://portal.softwarepublico.gov.br/social/pw3270/"
  2626 +
2462 2627 #~ msgid "Predefined color schemes"
2463 2628 #~ msgstr "Esquemas de cor pré-definidos"
2464 2629  
... ... @@ -2645,6 +2810,9 @@ msgstr &quot;translator-credits&quot;
2645 2810 #~ msgid "Revocation list"
2646 2811 #~ msgstr "Lista de revogados"
2647 2812  
  2813 +#~ msgid "Right"
  2814 +#~ msgstr "Direita"
  2815 +
2648 2816 #~ msgid "SOCKS4 Proxy: client is not reachable"
2649 2817 #~ msgstr "SOCKS4 Proxy: client is not reachable"
2650 2818  
... ... @@ -2773,6 +2941,12 @@ msgstr &quot;translator-credits&quot;
2773 2941 #~ msgid "SSLv2/v3 read server hello A"
2774 2942 #~ msgstr "SSLv2/v3 read server hello A"
2775 2943  
  2944 +#~ msgid "S_tyle"
  2945 +#~ msgstr "E_stilo"
  2946 +
  2947 +#~ msgid "Save As"
  2948 +#~ msgstr "Salvar Como"
  2949 +
2776 2950 #~ msgid "Save copied data"
2777 2951 #~ msgstr "Salvar cópia"
2778 2952  
... ... @@ -2782,6 +2956,9 @@ msgstr &quot;translator-credits&quot;
2782 2956 #~ msgid "Save copy to file"
2783 2957 #~ msgstr "Salvar cópia para arquivo"
2784 2958  
  2959 +#~ msgid "Save desktop icon"
  2960 +#~ msgstr "Salvar ícone da área de trabalho"
  2961 +
2785 2962 #~ msgid "Save desktop launcher"
2786 2963 #~ msgstr "Salvar lançador para área de trabalho"
2787 2964  
... ... @@ -2800,9 +2977,6 @@ msgstr &quot;translator-credits&quot;
2800 2977 #~ msgid "Save terminal contents"
2801 2978 #~ msgstr "Salvar conteúdo da tela"
2802 2979  
2803   -#~ msgid "Save trace file"
2804   -#~ msgstr "Salvar arquivo de trace"
2805   -
2806 2980 #~ msgid "Save trace to file"
2807 2981 #~ msgstr "Salvar trace para arquivo"
2808 2982  
... ... @@ -2865,12 +3039,12 @@ msgstr &quot;translator-credits&quot;
2865 3039 #~ msgid "Security warning"
2866 3040 #~ msgstr "Alerta de segurança"
2867 3041  
  3042 +#~ msgid "Select"
  3043 +#~ msgstr "Selecionar"
  3044 +
2868 3045 #~ msgid "Select destination file"
2869 3046 #~ msgstr "Selecionar arquivo destino"
2870 3047  
2871   -#~ msgid "Select file"
2872   -#~ msgstr "Selecionar arquivo"
2873   -
2874 3048 #~ msgid "Select file to receive"
2875 3049 #~ msgstr "Selecione arquivo a receber"
2876 3050  
... ... @@ -2895,6 +3069,9 @@ msgstr &quot;translator-credits&quot;
2895 3069 #~ msgid "Select previous file"
2896 3070 #~ msgstr "Selecionar arquivo anterior"
2897 3071  
  3072 +#~ msgid "Select the title bar itens"
  3073 +#~ msgstr "Selecione itens da barra de título"
  3074 +
2898 3075 #~ msgid "Select() failed when processing for events."
2899 3076 #~ msgstr "Select() falhou ao processar eventos."
2900 3077  
... ... @@ -2913,9 +3090,6 @@ msgstr &quot;translator-credits&quot;
2913 3090 #~ msgid "Send an \"Enter\" action."
2914 3091 #~ msgstr "Envia um \"Enter\"."
2915 3092  
2916   -#~ msgid "Send file"
2917   -#~ msgstr "Enviar arquivo"
2918   -
2919 3093 #~ msgid "Send file to host"
2920 3094 #~ msgstr "Enviar arquivo para o servidor"
2921 3095  
... ... @@ -3048,9 +3222,6 @@ msgstr &quot;translator-credits&quot;
3048 3222 #~ msgid "Start upload."
3049 3223 #~ msgstr "Iniciar envio."
3050 3224  
3051   -#~ msgid "Starting"
3052   -#~ msgstr "Iniciando"
3053   -
3054 3225 #~ msgid "Starting transfer"
3055 3226 #~ msgstr "Iniciando transferência"
3056 3227  
... ... @@ -3060,6 +3231,9 @@ msgstr &quot;translator-credits&quot;
3060 3231 #~ msgid "State is 3270, TN3270e or SSCP"
3061 3232 #~ msgstr "Estado do terminal é 3270, TN3270e or SSCP"
3062 3233  
  3234 +#~ msgid "Style"
  3235 +#~ msgstr "Estilo"
  3236 +
3063 3237 #~ msgid "Subject issuer mismatch"
3064 3238 #~ msgstr "Divergência na identidade do emissor"
3065 3239  
... ... @@ -3847,6 +4021,9 @@ msgstr &quot;translator-credits&quot;
3847 4021 #~ msgid "_Port:"
3848 4022 #~ msgstr "_Porta:"
3849 4023  
  4024 +#~ msgid "_Properties"
  4025 +#~ msgstr "_Propriedades"
  4026 +
3850 4027 #~ msgid "_Receive"
3851 4028 #~ msgstr "_Receber"
3852 4029  
... ... @@ -3895,6 +4072,19 @@ msgstr &quot;translator-credits&quot;
3895 4072 #~ msgid "fcntl() error when getting socket state."
3896 4073 #~ msgstr "erro fcntl() ao obter estado do socket."
3897 4074  
  4075 +#, fuzzy
  4076 +#~ msgctxt "PrjLabel"
  4077 +#~ msgid "https://github.com/PerryWerneck/pw3270"
  4078 +#~ msgstr "Portal do Software Público Brasileiro"
  4079 +
  4080 +#~ msgctxt "ProjectURLLabel"
  4081 +#~ msgid "https://github.com/PerryWerneck/pw3270"
  4082 +#~ msgstr "Portal do Software Público Brasileiro"
  4083 +
  4084 +#~ msgctxt "ProjectURL"
  4085 +#~ msgid "https://portal.softwarepublico.gov.br/social/pw3270/"
  4086 +#~ msgstr "https://portal.softwarepublico.gov.br/social/pw3270/"
  4087 +
3898 4088 #~ msgid "ioctl(%s)"
3899 4089 #~ msgstr "ioctl(%s)"
3900 4090  
... ...
locale/pw3270.pot
... ... @@ -8,7 +8,7 @@ msgid &quot;&quot;
8 8 msgstr ""
9 9 "Project-Id-Version: PACKAGE VERSION\n"
10 10 "Report-Msgid-Bugs-To: \n"
11   -"POT-Creation-Date: 2020-08-05 16:03-0300\n"
  11 +"POT-Creation-Date: 2020-10-15 13:43-0300\n"
12 12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14 "Language-Team: LANGUAGE <LL@li.org>\n"
... ... @@ -17,17 +17,37 @@ msgstr &quot;&quot;
17 17 "Content-Type: text/plain; charset=CHARSET\n"
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19  
20   -#: src/objects/application/application.c:208
  20 +#: src/objects/application/application.c:206
21 21 #, c-format
22 22 msgid "\"%s\" is not a valid user interface name"
23 23 msgstr ""
24 24  
25   -#: src/objects/application/actions/about.c:96
  25 +#: src/objects/application/actions/about.c:93
  26 +msgid "32 bits Linux"
  27 +msgstr ""
  28 +
  29 +#: src/objects/application/actions/about.c:91
  30 +msgid "32 bits Windows"
  31 +msgstr ""
  32 +
  33 +#: src/objects/actions/save.c:156 src/objects/os/linux/savedesktopicon.c:267
  34 +msgid "3270 session files"
  35 +msgstr ""
  36 +
  37 +#: src/objects/application/actions/about.c:87
26 38 #, c-format
27   -msgid "3270 terminal emulator for GTK %d.%d"
  39 +msgid "3270 terminal emulator for %s."
28 40 msgstr ""
29 41  
30   -#: src/objects/application/actions/about.c:161 ui/application.xml:39
  42 +#: src/objects/application/actions/about.c:95
  43 +msgid "64 bits Linux"
  44 +msgstr ""
  45 +
  46 +#: src/objects/application/actions/about.c:89
  47 +msgid "64 bits Windows"
  48 +msgstr ""
  49 +
  50 +#: src/objects/application/actions/about.c:188 ui/application.xml:39
31 51 #: ui/application.xml:537
32 52 msgid "About PW3270"
33 53 msgstr ""
... ... @@ -36,23 +56,23 @@ msgstr &quot;&quot;
36 56 msgid "Action Name"
37 57 msgstr ""
38 58  
39   -#: src/objects/window/window.c:163 src/objects/toolbar/toolbar.c:135
  59 +#: src/objects/window/window.c:184
40 60 msgid "Action Names"
41 61 msgstr ""
42 62  
43   -#: ui/window.xml:369 ui/window.xml:479 ui/application.xml:509
  63 +#: ui/window.xml:379 ui/window.xml:494 ui/application.xml:509
44 64 msgid "Alert sound"
45 65 msgstr ""
46 66  
47   -#: src/main/tools.c:99
  67 +#: src/main/tools.c:99 src/tools/entry.c:88
48 68 msgid "All files"
49 69 msgstr ""
50 70  
51   -#: ui/window.xml:168 ui/application.xml:251
  71 +#: ui/window.xml:178 ui/application.xml:251
52 72 msgid "Append to copy"
53 73 msgstr ""
54 74  
55   -#: src/objects/application/actions/about.c:126
  75 +#: src/objects/application/actions/about.c:129
56 76 msgid "Apple version"
57 77 msgstr ""
58 78  
... ... @@ -60,11 +80,15 @@ msgstr &quot;&quot;
60 80 msgid "Application"
61 81 msgstr ""
62 82  
63   -#: src/objects/application/actions/preferences.c:69 ui/application.xml:83
  83 +#: src/objects/window/header-settings.c:123
  84 +msgid "Application menu"
  85 +msgstr ""
  86 +
  87 +#: src/objects/application/actions/preferences.c:76 ui/application.xml:83
64 88 msgid "Application preferences"
65 89 msgstr ""
66 90  
67   -#: src/objects/window/page.c:263
  91 +#: src/objects/window/page.c:264
68 92 msgid "Apply"
69 93 msgstr ""
70 94  
... ... @@ -72,15 +96,15 @@ msgstr &quot;&quot;
72 96 msgid "Auto-Reconnect"
73 97 msgstr ""
74 98  
75   -#: src/objects/toolbar/settings.c:114
  99 +#: src/objects/toolbar/settings.c:112 src/objects/settings/actionview.c:73
76 100 msgid "Available"
77 101 msgstr ""
78 102  
79   -#: src/objects/application/actions/about.c:130
  103 +#: src/objects/application/actions/about.c:132
80 104 msgid "Based on X3270 from"
81 105 msgstr ""
82 106  
83   -#: ui/window.xml:398 ui/application.xml:474
  107 +#: ui/window.xml:408 ui/application.xml:474
84 108 msgid "Blank Fill"
85 109 msgstr ""
86 110  
... ... @@ -92,21 +116,17 @@ msgstr &quot;&quot;
92 116 msgid "Bold"
93 117 msgstr ""
94 118  
95   -#: src/objects/application/actions/about.c:142
96   -msgid "Brazilian Public Software Portal"
  119 +#: src/objects/window/terminal.c:165
  120 +msgid "Can't load session file"
97 121 msgstr ""
98 122  
99   -#: src/objects/window/terminal.c:197
  123 +#: src/objects/window/terminal.c:160
100 124 #, c-format
101   -msgid "Can't save file \"%s\""
102   -msgstr ""
103   -
104   -#: src/objects/window/terminal.c:202
105   -msgid "Can't save session file"
  125 +msgid "Can't use \"%s\""
106 126 msgstr ""
107 127  
108   -#: src/objects/actions/save.c:65 src/objects/application/actions/open.c:49
109   -#: src/objects/window/page.c:264
  128 +#: src/objects/application/actions/open.c:49 src/objects/window/page.c:265
  129 +#: src/tools/entry.c:71
110 130 msgid "Cancel"
111 131 msgstr ""
112 132  
... ... @@ -114,7 +134,19 @@ msgstr &quot;&quot;
114 134 msgid "Change terminal colors"
115 135 msgstr ""
116 136  
117   -#: ui/window.xml:182 ui/window.xml:324 ui/application.xml:304
  137 +#: src/objects/application/actions/preferences.c:78
  138 +msgid "Change the application preferences"
  139 +msgstr ""
  140 +
  141 +#: src/objects/window/header-settings.c:98
  142 +msgid "Change the position of the title bar icons"
  143 +msgstr ""
  144 +
  145 +#: src/objects/window/actions/sessionproperties.c:47
  146 +msgid "Change the preferences for the active session"
  147 +msgstr ""
  148 +
  149 +#: ui/window.xml:192 ui/window.xml:334 ui/application.xml:304
118 150 msgid "Clear"
119 151 msgstr ""
120 152  
... ... @@ -131,8 +163,8 @@ msgstr &quot;&quot;
131 163 msgid "Close the window"
132 164 msgstr ""
133 165  
134   -#: src/objects/window/actions/close.c:60 ui/window.xml:270 ui/window.xml:458
135   -#: ui/window.xml:560 ui/application.xml:216
  166 +#: src/objects/window/actions/close.c:60 ui/window.xml:280 ui/window.xml:473
  167 +#: ui/window.xml:580 ui/application.xml:216
136 168 msgid "Close window"
137 169 msgstr ""
138 170  
... ... @@ -140,6 +172,10 @@ msgstr &quot;&quot;
140 172 msgid "Colors"
141 173 msgstr ""
142 174  
  175 +#: src/objects/os/linux/savedesktopicon.c:101
  176 +msgid "Comment"
  177 +msgstr ""
  178 +
143 179 #: src/objects/window/actions/connect.c:59
144 180 msgid "Connect"
145 181 msgstr ""
... ... @@ -152,11 +188,15 @@ msgstr &quot;&quot;
152 188 msgid "Connect to host"
153 189 msgstr ""
154 190  
155   -#: src/objects/window/window.c:702 src/objects/window/page.c:217
  191 +#: src/objects/window/window.c:753 src/objects/window/page.c:218
156 192 msgid "Connected to host"
157 193 msgstr ""
158 194  
159   -#: src/objects/application/actions/about.c:127
  195 +#: src/tools/entry.c:131
  196 +msgid "Continue"
  197 +msgstr ""
  198 +
  199 +#: src/objects/application/actions/about.c:130
160 200 msgid "Contributors"
161 201 msgstr ""
162 202  
... ... @@ -164,6 +204,14 @@ msgstr &quot;&quot;
164 204 msgid "Copy"
165 205 msgstr ""
166 206  
  207 +#: ui/window.xml:168
  208 +msgid "Copy as HTML"
  209 +msgstr ""
  210 +
  211 +#: ui/window.xml:173
  212 +msgid "Copy as image"
  213 +msgstr ""
  214 +
167 215 #: ui/window.xml:163 ui/application.xml:246
168 216 msgid "Copy as table"
169 217 msgstr ""
... ... @@ -172,11 +220,11 @@ msgstr &quot;&quot;
172 220 msgid "Copy as text"
173 221 msgstr ""
174 222  
175   -#: src/objects/windows/savedesktopicon.c:79
176   -msgid "Create a desktop icon for the current session"
  223 +#: src/objects/os/linux/savedesktopicon.c:114
  224 +msgid "Create shortcut for the current session"
177 225 msgstr ""
178 226  
179   -#: ui/window.xml:359 ui/application.xml:459
  227 +#: ui/window.xml:369 ui/application.xml:459
180 228 msgid "Cross hair cursor"
181 229 msgstr ""
182 230  
... ... @@ -192,28 +240,24 @@ msgstr &quot;&quot;
192 240 msgid "Current session"
193 241 msgstr ""
194 242  
195   -#: ui/window.xml:173 ui/application.xml:256
  243 +#: ui/window.xml:183 ui/application.xml:256
196 244 msgid "Cut"
197 245 msgstr ""
198 246  
199   -#: ui/window.xml:192 ui/window.xml:334 ui/application.xml:314
  247 +#: ui/window.xml:202 ui/window.xml:344 ui/application.xml:314
200 248 msgid "Delete Field"
201 249 msgstr ""
202 250  
203   -#: ui/window.xml:93 ui/application.xml:158
204   -msgid "Desktop icon"
205   -msgstr ""
206   -
207   -#: ui/window.xml:265 ui/window.xml:453
  251 +#: ui/window.xml:275 ui/window.xml:468
208 252 msgid "Disconnect"
209 253 msgstr ""
210 254  
211   -#: src/objects/window/window.c:702 src/objects/window/window.c:729
212   -#: src/objects/window/page.c:206
  255 +#: src/objects/window/window.c:753 src/objects/window/window.c:780
  256 +#: src/objects/window/page.c:207
213 257 msgid "Disconnected from host"
214 258 msgstr ""
215 259  
216   -#: ui/window.xml:381 ui/window.xml:492 ui/application.xml:524
  260 +#: ui/window.xml:391 ui/window.xml:507 ui/application.xml:524
217 261 msgid "Dynamic font spacing"
218 262 msgstr ""
219 263  
... ... @@ -237,15 +281,19 @@ msgstr &quot;&quot;
237 281 msgid "Enabled"
238 282 msgstr ""
239 283  
240   -#: ui/window.xml:187 ui/window.xml:329 ui/application.xml:309
  284 +#: src/objects/settings/actionview.c:78
  285 +msgid "End"
  286 +msgstr ""
  287 +
  288 +#: ui/window.xml:197 ui/window.xml:339 ui/application.xml:309
241 289 msgid "Erase input"
242 290 msgstr ""
243 291  
244   -#: ui/window.xml:197 ui/window.xml:339 ui/application.xml:319
  292 +#: ui/window.xml:207 ui/window.xml:349 ui/application.xml:319
245 293 msgid "Erase to end of field"
246 294 msgstr ""
247 295  
248   -#: ui/window.xml:202 ui/window.xml:344 ui/application.xml:324
  296 +#: ui/window.xml:212 ui/window.xml:354 ui/application.xml:324
249 297 msgid "Erase to end of line"
250 298 msgstr ""
251 299  
... ... @@ -253,15 +301,11 @@ msgstr &quot;&quot;
253 301 msgid "Field attributes"
254 302 msgstr ""
255 303  
256   -#: src/objects/windows/savedesktopicon.c:62
257   -msgid "File name"
258   -msgstr ""
259   -
260 304 #: ui/application.xml:454
261 305 msgid "Full Screen"
262 306 msgstr ""
263 307  
264   -#: ui/window.xml:236 ui/window.xml:407 ui/window.xml:497
  308 +#: ui/window.xml:246 ui/window.xml:417 ui/window.xml:512
265 309 msgid "Full screen"
266 310 msgstr ""
267 311  
... ... @@ -269,6 +313,10 @@ msgstr &quot;&quot;
269 313 msgid "Function bar"
270 314 msgstr ""
271 315  
  316 +#: src/objects/os/linux/savedesktopicon.c:94
  317 +msgid "Generic name"
  318 +msgstr ""
  319 +
272 320 #: ui/application.xml:36 ui/application.xml:534
273 321 msgid "Help"
274 322 msgstr ""
... ... @@ -277,11 +325,11 @@ msgstr &quot;&quot;
277 325 msgid "Host properties"
278 326 msgstr ""
279 327  
280   -#: src/objects/window/window.c:469
  328 +#: src/objects/window/window.c:552 src/objects/os/linux/savedesktopicon.c:102
281 329 msgid "IBM 3270 Terminal emulator"
282 330 msgstr ""
283 331  
284   -#: src/objects/actions/view.c:89
  332 +#: src/objects/actions/view.c:90
285 333 msgid "Icon"
286 334 msgstr ""
287 335  
... ... @@ -289,19 +337,27 @@ msgstr &quot;&quot;
289 337 msgid "Icon Name"
290 338 msgstr ""
291 339  
292   -#: src/objects/toolbar/settings.c:50
  340 +#: src/objects/toolbar/settings.c:54
293 341 msgid "Icon Size"
294 342 msgstr ""
295 343  
296   -#: src/objects/toolbar/toolbar.c:262
  344 +#: src/objects/toolbar/settings.c:61
  345 +msgid "Icon Style"
  346 +msgstr ""
  347 +
  348 +#: src/objects/toolbar/models.c:52
297 349 msgid "Icon _size"
298 350 msgstr ""
299 351  
300   -#: src/objects/toolbar/toolbar.c:84
  352 +#: src/objects/toolbar/models.c:108
  353 +msgid "Icon type"
  354 +msgstr ""
  355 +
  356 +#: src/objects/toolbar/models.c:97
301 357 msgid "Icons & text"
302 358 msgstr ""
303 359  
304   -#: src/objects/toolbar/toolbar.c:74
  360 +#: src/objects/toolbar/models.c:87
305 361 msgid "Icons only"
306 362 msgstr ""
307 363  
... ... @@ -309,7 +365,7 @@ msgstr &quot;&quot;
309 365 msgid "If the action can be activated"
310 366 msgstr ""
311 367  
312   -#: ui/window.xml:469
  368 +#: ui/window.xml:484
313 369 msgid "Insert"
314 370 msgstr ""
315 371  
... ... @@ -317,7 +373,15 @@ msgstr &quot;&quot;
317 373 msgid "Invalid or unknown property type"
318 374 msgstr ""
319 375  
320   -#: src/objects/toolbar/settings.c:108
  376 +#: src/objects/settings/actionview.c:79
  377 +msgid "Items packed from the end to the start"
  378 +msgstr ""
  379 +
  380 +#: src/objects/settings/actionview.c:69
  381 +msgid "Items packed from the start to the end"
  382 +msgstr ""
  383 +
  384 +#: src/objects/toolbar/settings.c:106
321 385 msgid "Itens"
322 386 msgstr ""
323 387  
... ... @@ -345,20 +409,24 @@ msgstr &quot;&quot;
345 409 msgid "Keypads"
346 410 msgstr ""
347 411  
348   -#: src/objects/actions/view.c:98
  412 +#: src/objects/application/actions/about.c:140
  413 +msgid "LICENSE"
  414 +msgstr ""
  415 +
  416 +#: src/objects/actions/view.c:99
349 417 msgid "Label"
350 418 msgstr ""
351 419  
352   -#: src/objects/toolbar/toolbar.c:58
  420 +#: src/objects/toolbar/models.c:66
353 421 msgid "Large"
354 422 msgstr ""
355 423  
356   -#: src/objects/windows/savedesktopicon.c:67
357   -msgid "Launcher name"
  424 +#: src/objects/toolbar/settings.c:176
  425 +msgid "Layout"
358 426 msgstr ""
359 427  
360   -#: src/objects/toolbar/settings.c:207
361   -msgid "Layout"
  428 +#: src/objects/settings/actionview.c:74
  429 +msgid "List of the available and unpacked actions"
362 430 msgstr ""
363 431  
364 432 #: ui/application.xml:71
... ... @@ -369,11 +437,11 @@ msgstr &quot;&quot;
369 437 msgid "Main Toolbar"
370 438 msgstr ""
371 439  
372   -#: ui/window.xml:540
  440 +#: ui/window.xml:555
373 441 msgid "Main menu"
374 442 msgstr ""
375 443  
376   -#: src/objects/application/actions/about.c:125
  444 +#: src/objects/application/actions/about.c:128
377 445 msgid "Maintainers"
378 446 msgstr ""
379 447  
... ... @@ -381,23 +449,23 @@ msgstr &quot;&quot;
381 449 msgid "Menu"
382 450 msgstr ""
383 451  
384   -#: ui/window.xml:506 ui/application.xml:403
  452 +#: ui/window.xml:521 ui/application.xml:403
385 453 msgid "Model 2 - 80x24"
386 454 msgstr ""
387 455  
388   -#: ui/window.xml:511 ui/application.xml:408
  456 +#: ui/window.xml:526 ui/application.xml:408
389 457 msgid "Model 3 - 80x32"
390 458 msgstr ""
391 459  
392   -#: ui/window.xml:516 ui/application.xml:413
  460 +#: ui/window.xml:531 ui/application.xml:413
393 461 msgid "Model 4 - 80x43"
394 462 msgstr ""
395 463  
396   -#: ui/window.xml:521 ui/application.xml:418
  464 +#: ui/window.xml:536 ui/application.xml:418
397 465 msgid "Model 5 - 132x27"
398 466 msgstr ""
399 467  
400   -#: ui/window.xml:376 ui/application.xml:444
  468 +#: ui/window.xml:386 ui/application.xml:444
401 469 msgid "Monocase"
402 470 msgstr ""
403 471  
... ... @@ -405,7 +473,7 @@ msgstr &quot;&quot;
405 473 msgid "Network keep alive"
406 474 msgstr ""
407 475  
408   -#: src/objects/window/page.c:274
  476 +#: src/objects/window/page.c:275
409 477 msgid "New session name"
410 478 msgstr ""
411 479  
... ... @@ -453,7 +521,7 @@ msgstr &quot;&quot;
453 521 msgid "Open session in New window"
454 522 msgstr ""
455 523  
456   -#: ui/window.xml:212 ui/window.xml:354 ui/window.xml:489 ui/application.xml:431
  524 +#: ui/window.xml:222 ui/window.xml:364 ui/window.xml:504 ui/application.xml:431
457 525 msgid "Options"
458 526 msgstr ""
459 527  
... ... @@ -461,22 +529,26 @@ msgstr &quot;&quot;
461 529 msgid "Parameter Type"
462 530 msgstr ""
463 531  
464   -#: ui/window.xml:286 ui/application.xml:261
  532 +#: ui/window.xml:296 ui/application.xml:261
465 533 msgid "Paste from clipboard"
466 534 msgstr ""
467 535  
468   -#: ui/window.xml:296 ui/application.xml:271
  536 +#: ui/window.xml:306 ui/application.xml:271
469 537 msgid "Paste from text file"
470 538 msgstr ""
471 539  
472   -#: ui/window.xml:291 ui/application.xml:266
  540 +#: ui/window.xml:301 ui/application.xml:266
473 541 msgid "Paste next"
474 542 msgstr ""
475 543  
476   -#: ui/window.xml:393 ui/application.xml:469
  544 +#: ui/window.xml:403 ui/application.xml:469
477 545 msgid "Paste with left margin"
478 546 msgstr ""
479 547  
  548 +#: src/objects/os/linux/savedesktopicon.c:71
  549 +msgid "Path for the new shortcut"
  550 +msgstr ""
  551 +
480 552 #: ui/window.xml:129
481 553 msgid "Preferences"
482 554 msgstr ""
... ... @@ -485,11 +557,11 @@ msgstr &quot;&quot;
485 557 msgid "Print"
486 558 msgstr ""
487 559  
488   -#: ui/window.xml:439
  560 +#: ui/window.xml:454
489 561 msgid "Print screen"
490 562 msgstr ""
491 563  
492   -#: ui/window.xml:252
  564 +#: ui/window.xml:262
493 565 msgid "Print selected"
494 566 msgstr ""
495 567  
... ... @@ -502,15 +574,15 @@ msgstr &quot;&quot;
502 574 msgid "Quit"
503 575 msgstr ""
504 576  
505   -#: src/objects/window/page.c:261
  577 +#: src/objects/window/page.c:262
506 578 msgid "Rename Session"
507 579 msgstr ""
508 580  
509   -#: ui/window.xml:315 ui/application.xml:295
  581 +#: ui/window.xml:325 ui/application.xml:295
510 582 msgid "Reselect"
511 583 msgstr ""
512 584  
513   -#: ui/window.xml:364 ui/application.xml:464
  585 +#: ui/window.xml:374 ui/application.xml:464
514 586 msgid "Resize on alternate screen"
515 587 msgstr ""
516 588  
... ... @@ -518,55 +590,59 @@ msgstr &quot;&quot;
518 590 msgid "Right keypad"
519 591 msgstr ""
520 592  
521   -#: src/objects/toolbar/toolbar.c:286
522   -msgid "S_tyle"
  593 +#: ui/window.xml:69 ui/application.xml:134
  594 +msgid "Save"
523 595 msgstr ""
524 596  
525   -#: src/objects/actions/save.c:64 ui/window.xml:69 ui/application.xml:134
526   -msgid "Save"
  597 +#: src/objects/actions/save.c:77
  598 +msgid "Save current session preferences to file"
527 599 msgstr ""
528 600  
529   -#: src/objects/actions/save.c:49
530   -msgid "Save As"
  601 +#: ui/window.xml:449
  602 +msgid "Save screen"
531 603 msgstr ""
532 604  
533   -#: src/objects/windows/savedesktopicon.c:78
534   -msgid "Save desktop icon"
  605 +#: ui/window.xml:257
  606 +msgid "Save selected"
535 607 msgstr ""
536 608  
537   -#: ui/window.xml:434
538   -msgid "Save screen"
  609 +#: src/objects/actions/save.c:75 src/objects/actions/save.c:153
  610 +msgid "Save session preferences"
539 611 msgstr ""
540 612  
541   -#: ui/window.xml:247
542   -msgid "Save selected"
  613 +#: src/objects/os/linux/savedesktopicon.c:113
  614 +msgid "Save session shortcut"
  615 +msgstr ""
  616 +
  617 +#: src/objects/os/linux/savedesktopicon.c:264
  618 +msgid "Save to session filename"
543 619 msgstr ""
544 620  
545   -#: src/objects/actions/save.c:51
546   -msgid "Save session properties"
  621 +#: src/objects/os/linux/savedesktopicon.c:236
  622 +msgid "Save to shortcut file"
547 623 msgstr ""
548 624  
549   -#: ui/window.xml:503 ui/application.xml:400
  625 +#: ui/window.xml:518 ui/application.xml:400
550 626 msgid "Screen size"
551 627 msgstr ""
552 628  
553   -#: ui/window.xml:310 ui/application.xml:285
  629 +#: ui/window.xml:320 ui/application.xml:285
554 630 msgid "Select Field"
555 631 msgstr ""
556 632  
557   -#: ui/window.xml:305 ui/application.xml:280
  633 +#: ui/window.xml:315 ui/application.xml:280
558 634 msgid "Select all"
559 635 msgstr ""
560 636  
561   -#: ui/window.xml:217 ui/application.xml:479
  637 +#: ui/window.xml:227 ui/application.xml:479
562 638 msgid "Select by rectangles"
563 639 msgstr ""
564 640  
565   -#: src/objects/toolbar/settings.c:108
  641 +#: src/objects/toolbar/settings.c:106
566 642 msgid "Select the toolbar itens"
567 643 msgstr ""
568 644  
569   -#: src/objects/toolbar/settings.c:113
  645 +#: src/objects/toolbar/settings.c:111
570 646 msgid "Selected"
571 647 msgstr ""
572 648  
... ... @@ -579,12 +655,12 @@ msgstr &quot;&quot;
579 655 msgid "Send/Receive"
580 656 msgstr ""
581 657  
582   -#: src/objects/window/actions/filetransfer.c:46 ui/window.xml:444
  658 +#: src/objects/window/actions/filetransfer.c:46 ui/window.xml:459
583 659 #: ui/application.xml:195
584 660 msgid "Send/Receive files"
585 661 msgstr ""
586 662  
587   -#: src/objects/toolbar/settings.c:266 src/objects/toolbar/settings.c:276
  663 +#: src/objects/toolbar/settings.c:234 src/objects/toolbar/settings.c:244
588 664 msgid "Separator"
589 665 msgstr ""
590 666  
... ... @@ -592,10 +668,14 @@ msgstr &quot;&quot;
592 668 msgid "Session"
593 669 msgstr ""
594 670  
595   -#: ui/application.xml:76
  671 +#: ui/window.xml:440 ui/window.xml:560 ui/application.xml:76
596 672 msgid "Session Trace"
597 673 msgstr ""
598 674  
  675 +#: src/objects/actions/save.c:63 src/objects/os/linux/savedesktopicon.c:85
  676 +msgid "Session file"
  677 +msgstr ""
  678 +
599 679 #: ui/window.xml:61 ui/application.xml:126
600 680 msgid "Session in New Tab"
601 681 msgstr ""
... ... @@ -604,12 +684,16 @@ msgstr &quot;&quot;
604 684 msgid "Session in new window"
605 685 msgstr ""
606 686  
607   -#: src/objects/window/actions/sessionproperties.c:45 ui/window.xml:98
608   -#: ui/window.xml:554 ui/application.xml:163
609   -msgid "Session properties"
  687 +#: src/objects/actions/save.c:56 src/objects/os/linux/savedesktopicon.c:77
  688 +msgid "Session name"
  689 +msgstr ""
  690 +
  691 +#: src/objects/window/actions/sessionproperties.c:46 ui/window.xml:98
  692 +#: ui/window.xml:574 ui/application.xml:163
  693 +msgid "Session preferences"
610 694 msgstr ""
611 695  
612   -#: src/objects/application/application.c:221
  696 +#: src/objects/application/application.c:219
613 697 msgid "Set the user-interface type"
614 698 msgstr ""
615 699  
... ... @@ -617,34 +701,58 @@ msgstr &quot;&quot;
617 701 msgid "Settings"
618 702 msgstr ""
619 703  
620   -#: src/objects/toolbar/settings.c:207
  704 +#: src/objects/toolbar/settings.c:176
621 705 msgid "Setup the toolbar layout"
622 706 msgstr ""
623 707  
624   -#: src/objects/toolbar/settings.c:90
  708 +#: src/objects/window/header-settings.c:87
  709 +msgid "Setup title bar"
  710 +msgstr ""
  711 +
  712 +#: src/objects/toolbar/toolbar.c:214 src/objects/toolbar/settings.c:88
625 713 msgid "Setup toolbar"
626 714 msgstr ""
627 715  
  716 +#: src/objects/os/linux/savedesktopicon.c:70
  717 +msgid "Shortcut file"
  718 +msgstr ""
  719 +
  720 +#: ui/window.xml:93 ui/application.xml:158
  721 +msgid "Shortcut for this session"
  722 +msgstr ""
  723 +
  724 +#: src/objects/os/linux/savedesktopicon.c:63
  725 +msgid "Shortcut name"
  726 +msgstr ""
  727 +
628 728 #: ui/application.xml:494
629 729 msgid "Show Underline"
630 730 msgstr ""
631 731  
632   -#: ui/window.xml:231
  732 +#: ui/window.xml:241
633 733 msgid "Show menu"
634 734 msgstr ""
635 735  
636   -#: ui/window.xml:226
  736 +#: ui/window.xml:236
637 737 msgid "Show toolbar"
638 738 msgstr ""
639 739  
640   -#: src/objects/toolbar/toolbar.c:53
  740 +#: src/objects/toolbar/models.c:61
641 741 msgid "Small"
642 742 msgstr ""
643 743  
644   -#: ui/window.xml:388 ui/application.xml:504
  744 +#: ui/window.xml:398 ui/application.xml:504
645 745 msgid "Smart paste"
646 746 msgstr ""
647 747  
  748 +#: src/objects/os/linux/savedesktopicon.c:239
  749 +msgid "Standard desktop files"
  750 +msgstr ""
  751 +
  752 +#: src/objects/settings/actionview.c:68
  753 +msgid "Start"
  754 +msgstr ""
  755 +
648 756 #: src/objects/actions/abstract.c:152
649 757 msgid "State"
650 758 msgstr ""
... ... @@ -653,11 +761,12 @@ msgstr &quot;&quot;
653 761 msgid "State Type"
654 762 msgstr ""
655 763  
656   -#: src/objects/toolbar/settings.c:55
657   -msgid "Style"
  764 +#: src/objects/toolbar/models.c:115
  765 +msgid "Symbolic"
658 766 msgstr ""
659 767  
660   -#: src/objects/toolbar/toolbar.c:47 src/objects/toolbar/toolbar.c:69
  768 +#: src/objects/toolbar/models.c:55 src/objects/toolbar/models.c:82
  769 +#: src/objects/toolbar/models.c:111
661 770 msgid "System default"
662 771 msgstr ""
663 772  
... ... @@ -673,7 +782,7 @@ msgstr &quot;&quot;
673 782 msgid "Terminal font"
674 783 msgstr ""
675 784  
676   -#: src/objects/toolbar/toolbar.c:79
  785 +#: src/objects/toolbar/models.c:92
677 786 msgid "Text only"
678 787 msgstr ""
679 788  
... ... @@ -693,6 +802,14 @@ msgstr &quot;&quot;
693 802 msgid "The code of the User interface type"
694 803 msgstr ""
695 804  
  805 +#: src/objects/actions/save.c:64
  806 +msgid "The file to save the current session preferences"
  807 +msgstr ""
  808 +
  809 +#: src/objects/os/linux/savedesktopicon.c:86
  810 +msgid "The file with the session preferences for this shortcut"
  811 +msgstr ""
  812 +
696 813 #: src/objects/actions/abstract.c:110
697 814 msgid "The label for the action"
698 815 msgstr ""
... ... @@ -701,11 +818,11 @@ msgstr &quot;&quot;
701 818 msgid "The name of associated action"
702 819 msgstr ""
703 820  
704   -#: src/objects/window/window.c:164
  821 +#: src/objects/window/window.c:185
705 822 msgid "The name of the actions in the header bar"
706 823 msgstr ""
707 824  
708   -#: src/objects/toolbar/toolbar.c:136
  825 +#: src/objects/toolbar/toolbar.c:98
709 826 msgid "The name of the actions in the toolbar"
710 827 msgstr ""
711 828  
... ... @@ -729,15 +846,23 @@ msgstr &quot;&quot;
729 846 msgid "The position of the keypad"
730 847 msgstr ""
731 848  
  849 +#: src/objects/actions/save.c:57 src/objects/os/linux/savedesktopicon.c:79
  850 +msgid "The session name used in the window/tab title (empty for default)"
  851 +msgstr ""
  852 +
732 853 #: src/objects/actions/abstract.c:153
733 854 msgid "The state the action is in"
734 855 msgstr ""
735 856  
736   -#: src/objects/toolbar/toolbar.c:147
  857 +#: src/objects/toolbar/toolbar.c:109
737 858 msgid "The toolbar icon size"
738 859 msgstr ""
739 860  
740   -#: src/objects/toolbar/toolbar.c:160
  861 +#: src/objects/toolbar/toolbar.c:135
  862 +msgid "The toolbar icon type"
  863 +msgstr ""
  864 +
  865 +#: src/objects/toolbar/toolbar.c:122
741 866 msgid "The toolbar style"
742 867 msgstr ""
743 868  
... ... @@ -753,12 +878,28 @@ msgstr &quot;&quot;
753 878 msgid "The type of the state kept by the action"
754 879 msgstr ""
755 880  
756   -#: src/objects/toolbar/settings.c:89 ui/window.xml:420 ui/window.xml:535
  881 +#: src/objects/window/header-settings.c:86
  882 +msgid "Title bar"
  883 +msgstr ""
  884 +
  885 +#: src/objects/window/header-settings.c:98
  886 +msgid "Title bar actions"
  887 +msgstr ""
  888 +
  889 +#: src/objects/toolbar/settings.c:87 ui/window.xml:430 ui/window.xml:550
757 890 #: ui/application.xml:342
758 891 msgid "Toolbar"
759 892 msgstr ""
760 893  
761   -#: ui/window.xml:425
  894 +#: src/objects/toolbar/settings.c:68
  895 +msgid "Toolbar Style"
  896 +msgstr ""
  897 +
  898 +#: src/objects/toolbar/models.c:79
  899 +msgid "Toolbar s_tyle"
  900 +msgstr ""
  901 +
  902 +#: ui/window.xml:435
762 903 msgid "Top menu"
763 904 msgstr ""
764 905  
... ... @@ -766,7 +907,7 @@ msgstr &quot;&quot;
766 907 msgid "Trace"
767 908 msgstr ""
768 909  
769   -#: ui/window.xml:474 ui/application.xml:449
  910 +#: ui/window.xml:489 ui/application.xml:449
770 911 msgid "Track Cursor"
771 912 msgstr ""
772 913  
... ... @@ -774,7 +915,7 @@ msgstr &quot;&quot;
774 915 msgid "UI Type"
775 916 msgstr ""
776 917  
777   -#: ui/window.xml:257 ui/application.xml:290
  918 +#: ui/window.xml:267 ui/application.xml:290
778 919 msgid "Unselect"
779 920 msgstr ""
780 921  
... ... @@ -782,34 +923,38 @@ msgstr &quot;&quot;
782 923 msgid "Use +/- for field navigation"
783 924 msgstr ""
784 925  
785   -#: src/objects/application/actions/about.c:86
786   -#: src/objects/application/actions/about.c:88
  926 +#: src/objects/application/actions/about.c:70
787 927 #, c-format
788 928 msgid "Version %s-%s"
789 929 msgstr ""
790 930  
791   -#: src/objects/window/header.c:66 ui/window.xml:417 ui/window.xml:532
  931 +#: src/objects/window/header.c:66 ui/window.xml:427 ui/window.xml:547
792 932 #: ui/application.xml:63
793 933 msgid "View"
794 934 msgstr ""
795 935  
  936 +#: src/objects/application/actions/about.c:163
  937 +msgid "View this project on github"
  938 +msgstr ""
  939 +
796 940 #: ui/window.xml:40 ui/application.xml:105
797 941 msgid "Window with default session"
798 942 msgstr ""
799 943  
800   -#: src/objects/settings/dialog.c:84
  944 +#: src/objects/settings/dialog.c:79
801 945 msgid "_Apply"
802 946 msgstr ""
803 947  
804   -#: src/objects/settings/dialog.c:83 src/objects/windows/savedesktopicon.c:104
  948 +#: src/objects/actions/save.c:102 src/objects/settings/dialog.c:78
  949 +#: src/objects/os/linux/savedesktopicon.c:174
805 950 msgid "_Cancel"
806 951 msgstr ""
807 952  
808   -#: src/objects/window/page.c:394
  953 +#: src/objects/window/page.c:371
809 954 msgid "_Close session"
810 955 msgstr ""
811 956  
812   -#: ui/window.xml:549 ui/application.xml:368
  957 +#: ui/window.xml:569 ui/application.xml:368
813 958 msgid "_Connect"
814 959 msgstr ""
815 960  
... ... @@ -817,7 +962,7 @@ msgstr &quot;&quot;
817 962 msgid "_Disconnect"
818 963 msgstr ""
819 964  
820   -#: ui/window.xml:148 ui/window.xml:281 ui/application.xml:231
  965 +#: ui/window.xml:148 ui/window.xml:291 ui/application.xml:231
821 966 msgid "_Edit"
822 967 msgstr ""
823 968  
... ... @@ -837,15 +982,15 @@ msgstr &quot;&quot;
837 982 msgid "_Open"
838 983 msgstr ""
839 984  
840   -#: src/objects/toolbar/toolbar.c:308
841   -msgid "_Properties"
  985 +#: src/objects/toolbar/toolbar.c:236
  986 +msgid "_Preferences"
842 987 msgstr ""
843 988  
844   -#: src/objects/window/page.c:388
  989 +#: src/objects/window/page.c:365
845 990 msgid "_Rename session"
846 991 msgstr ""
847 992  
848   -#: src/objects/windows/savedesktopicon.c:105
  993 +#: src/objects/actions/save.c:103 src/objects/os/linux/savedesktopicon.c:175
849 994 msgid "_Save"
850 995 msgstr ""
851 996  
... ... @@ -853,6 +998,10 @@ msgstr &quot;&quot;
853 998 msgid "_View"
854 999 msgstr ""
855 1000  
856   -#: src/objects/application/actions/about.c:145
  1001 +#: src/objects/application/actions/about.c:162
  1002 +msgid "https://github.com/PerryWerneck/pw3270"
  1003 +msgstr ""
  1004 +
  1005 +#: src/objects/application/actions/about.c:165
857 1006 msgid "translator-credits"
858 1007 msgstr ""
... ...
pw3270.cbp
... ... @@ -43,13 +43,18 @@
43 43 <Unit filename="Makefile.in" />
44 44 <Unit filename="configure.ac" />
45 45 <Unit filename="schemas/linux/application.gschema.xml.in" />
  46 + <Unit filename="schemas/linux/window.gschema.xml.in" />
  47 + <Unit filename="schemas/windows/application.gschema.xml.in" />
  48 + <Unit filename="schemas/windows/window.gschema.xml.in" />
46 49 <Unit filename="src/include/pw3270.h" />
47 50 <Unit filename="src/include/pw3270/actions.h" />
48 51 <Unit filename="src/include/pw3270/application.h" />
49 52 <Unit filename="src/include/pw3270/keypad.h" />
50 53 <Unit filename="src/include/pw3270/settings.h" />
51 54 <Unit filename="src/include/pw3270/toolbar.h" />
  55 + <Unit filename="src/include/pw3270/tools.h" />
52 56 <Unit filename="src/include/pw3270/window.h" />
  57 + <Unit filename="src/include/v3270/keyfile.h" />
53 58 <Unit filename="src/main/main.c">
54 59 <Option compilerVar="CC" />
55 60 </Unit>
... ... @@ -126,7 +131,13 @@
126 131 <Unit filename="src/objects/keypad/widget.c">
127 132 <Option compilerVar="CC" />
128 133 </Unit>
129   - <Unit filename="src/objects/linux/savedesktopicon.c">
  134 + <Unit filename="src/objects/os/linux/savedesktopicon.c">
  135 + <Option compilerVar="CC" />
  136 + </Unit>
  137 + <Unit filename="src/objects/os/windows/savedesktopicon.c">
  138 + <Option compilerVar="CC" />
  139 + </Unit>
  140 + <Unit filename="src/objects/settings/actionview.c">
130 141 <Option compilerVar="CC" />
131 142 </Unit>
132 143 <Unit filename="src/objects/settings/dialog.c">
... ... @@ -138,6 +149,9 @@
138 149 <Unit filename="src/objects/toolbar/actions.c">
139 150 <Option compilerVar="CC" />
140 151 </Unit>
  152 + <Unit filename="src/objects/toolbar/models.c">
  153 + <Option compilerVar="CC" />
  154 + </Unit>
141 155 <Unit filename="src/objects/toolbar/private.h" />
142 156 <Unit filename="src/objects/toolbar/settings.c">
143 157 <Option compilerVar="CC" />
... ... @@ -163,9 +177,15 @@
163 177 <Unit filename="src/objects/window/actions/setcolors.c">
164 178 <Option compilerVar="CC" />
165 179 </Unit>
  180 + <Unit filename="src/objects/window/header-settings.c">
  181 + <Option compilerVar="CC" />
  182 + </Unit>
166 183 <Unit filename="src/objects/window/header.c">
167 184 <Option compilerVar="CC" />
168 185 </Unit>
  186 + <Unit filename="src/objects/window/keyfile.c">
  187 + <Option compilerVar="CC" />
  188 + </Unit>
169 189 <Unit filename="src/objects/window/page.c">
170 190 <Option compilerVar="CC" />
171 191 </Unit>
... ... @@ -179,7 +199,7 @@
179 199 <Unit filename="src/objects/window/window.c">
180 200 <Option compilerVar="CC" />
181 201 </Unit>
182   - <Unit filename="src/objects/windows/savedesktopicon.c">
  202 + <Unit filename="src/tools/entry.c">
183 203 <Option compilerVar="CC" />
184 204 </Unit>
185 205 <Unit filename="ui/application.xml" />
... ...
rpm/_service
... ... @@ -8,7 +8,7 @@
8 8 <param name="changesgenerate">enable</param>
9 9 <param name="changesauthor">perry.werneck@gmail.com</param>
10 10  
11   - <param name="versionformat">@PARENT_TAG@</param>
  11 + <param name="versionformat">@PARENT_TAG@+git%cd</param>
12 12 <param name="scm">git</param>
13 13 </service>
14 14  
... ...
rpm/pw3270.spec
... ... @@ -22,17 +22,17 @@
22 22  
23 23 #---[ Packaging ]-----------------------------------------------------------------------------------------------------
24 24  
25   -Name: pw3270
26   -Version: 5.3
27   -Release: 0
28   -Summary: IBM 3270 Terminal emulator for GTK
29   -License: GPL-2.0
30   -Group: System/X11/Terminals
31   -Url: https://portal.softwarepublico.gov.br/social/pw3270/
  25 +Name: pw3270
  26 +Version: 5.3
  27 +Release: 0
  28 +Summary: IBM 3270 Terminal emulator for GTK
  29 +License: GPL-2.0
  30 +Group: System/X11/Terminals
  31 +Url: https://github.com/PerryWerneck/pw3270
32 32  
33   -Source: pw3270-%{version}.tar.xz
  33 +Source: pw3270-%{version}.tar.xz
34 34  
35   -BuildRoot: %{_tmppath}/%{name}-%{version}-build
  35 +BuildRoot: %{_tmppath}/%{name}-%{version}-build
36 36  
37 37 Requires: shared-mime-info
38 38 Requires: %{name}-branding = %{version}
... ... @@ -41,7 +41,6 @@ BuildRequires: update-desktop-files
41 41  
42 42 %glib2_gsettings_schema_requires
43 43  
44   -
45 44 #--[ Setup by distribution ]------------------------------------------------------------------------------------------
46 45 #
47 46 # References:
... ... @@ -56,7 +55,7 @@ BuildRequires: update-desktop-files
56 55 BuildRequires: gtk3-devel
57 56 BuildRequires: glib2-devel
58 57 BuildRequires: librsvg2-tools
59   -BuildRequires: libv3270-devel >= %{version}
  58 +BuildRequires: libv3270-devel >= 5.3
60 59  
61 60 %endif
62 61  
... ... @@ -66,7 +65,7 @@ BuildRequires: libv3270-devel &gt;= %{version}
66 65  
67 66 BuildRequires: gtk3-devel
68 67 BuildRequires: glib2-devel
69   -BuildRequires: libv3270-devel
  68 +BuildRequires: libv3270-devel >= 5.3
70 69  
71 70 # Required for genmarshal
72 71 BuildRequires: python
... ... @@ -79,7 +78,7 @@ BuildRequires: python
79 78  
80 79 BuildRequires: pkgconfig(gtk+-3.0)
81 80 BuildRequires: pkgconfig(glib-2.0)
82   -BuildRequires: pkgconfig(libv3270) >= %{version}
  81 +BuildRequires: pkgconfig(libv3270) >= 5.3
83 82  
84 83 %endif
85 84  
... ... @@ -89,7 +88,7 @@ BuildRequires: pkgconfig(libv3270) &gt;= %{version}
89 88  
90 89 BuildRequires: pkgconfig(gtk+-3.0)
91 90 BuildRequires: pkgconfig(glib-2.0)
92   -BuildRequires: pkgconfig(libv3270) >= %{version}
  91 +BuildRequires: pkgconfig(libv3270) >= 5.3
93 92  
94 93 %endif
95 94  
... ... @@ -192,6 +191,7 @@ make all -j1
192 191 %{_datadir}/%{_product}/*.png
193 192 %{_datadir}/applications/*.desktop
194 193 %{_datadir}/pixmaps/*.png
  194 +%{_datadir}/mime/packages/*.xml
195 195  
196 196 %files keypads
197 197 %{_datadir}/%{_product}/keypad/*
... ...
schemas/linux/window.gschema.xml.in
... ... @@ -82,19 +82,37 @@
82 82  
83 83 <key name="toolbar-icon-size" type="i">
84 84 <default>0</default>
85   - <summary>The size of the icons in a toolbar</summary>
  85 + <summary>The size of the toolbar icons</summary>
  86 + <description></description>
  87 + </key>
  88 +
  89 + <key name="toolbar-icon-type" type="i">
  90 + <default>0</default>
  91 + <summary>Use symbolic icons on toolbar</summary>
  92 + <description></description>
  93 + </key>
  94 +
  95 + <key name="header-icon-type" type="i">
  96 + <default>0</default>
  97 + <summary>Use symbolic icons on title bar</summary>
  98 + <description></description>
  99 + </key>
  100 +
  101 + <key name="toolbar-position" type="i">
  102 + <default>0</default>
  103 + <summary>The toolbar position</summary>
86 104 <description></description>
87 105 </key>
88 106  
89 107 <key name="toolbar-action-names" type="s">
90   - <default>'win.copy,win.paste,win.select-all,separator,win.connect,win.disconnect,separator,win.session.properties,win.file.transfer,win.print,win.close'</default>
  108 + <default>'win.copy,win.paste,win.select-all,separator,win.clear,win.erase-input,separator,win.print,separator,win.zoom-out,win.zoom-fit-best,win.zoom-in'</default>
91 109 <summary>The toolbar action list</summary>
92 110 <description></description>
93 111 </key>
94 112  
95 113 <key name="header-action-names" type="s">
96   - <default>'win.disconnect,win.reconnect,win.file.transfer,win.print:menu.open-menu'</default>
97   - <summary>The actions in the header bar</summary>
  114 + <default>':menu.open-menu,win.disconnect,win.reconnect'</default>
  115 + <summary>The title bar action list</summary>
98 116 <description></description>
99 117 </key>
100 118  
... ...
schemas/windows/window.gschema.xml.in
... ... @@ -82,7 +82,25 @@
82 82  
83 83 <key name="toolbar-icon-size" type="i">
84 84 <default>2</default>
85   - <summary>The size of the icons in a toolbar</summary>
  85 + <summary>The size of the toolbar icons</summary>
  86 + <description></description>
  87 + </key>
  88 +
  89 + <key name="toolbar-icon-type" type="i">
  90 + <default>0</default>
  91 + <summary>Use symbolic icons on toolbar</summary>
  92 + <description></description>
  93 + </key>
  94 +
  95 + <key name="header-icon-type" type="i">
  96 + <default>0</default>
  97 + <summary>Use symbolic icons on title bar</summary>
  98 + <description></description>
  99 + </key>
  100 +
  101 + <key name="toolbar-position" type="i">
  102 + <default>0</default>
  103 + <summary>The toolbar position</summary>
86 104 <description></description>
87 105 </key>
88 106  
... ...
src/include/pw3270.h
... ... @@ -68,13 +68,6 @@
68 68  
69 69 void gtk_file_chooser_set_pw3270_filters(GtkFileChooser *chooser);
70 70  
71   - const gchar * v3270_get_session_filename(GtkWidget *widget);
72   - void v3270_set_session_filename(GtkWidget *widget, const gchar *filename);
73   - GKeyFile * v3270_get_session_keyfile(GtkWidget *widget);
74   -
75   - /// @brief Check if the terminal has a customized session file.
76   - gboolean v3270_allow_custom_settings(GtkWidget *widget);
77   -
78 71 G_END_DECLS
79 72  
80 73 #endif // PW3270_H_INCLUDED
... ...
src/include/pw3270/actions.h
... ... @@ -90,15 +90,26 @@
90 90 //
91 91 typedef GSList Pw3270ActionList;
92 92  
  93 + typedef enum _pw3270ActionViewFlag {
  94 + PW3270_ACTION_VIEW_FLAG_FIXED = 0, ///< @brief Don't move to other views.
  95 + PW3270_ACTION_VIEW_FLAG_ALLOW_ADD = 1, ///< @brief Allow add to target view.
  96 + PW3270_ACTION_VIEW_ALLOW_REMOVE = 2, ///< @brief Allow remove from source view.
  97 + PW3270_ACTION_VIEW_ALLOW_MOVE = 3 ///< @brief Allow move from one view to another.
  98 + } PW3270ActionViewFlag;
  99 +
  100 +
93 101 GtkWidget * pw3270_action_view_new();
94   - Pw3270ActionList * pw3270_action_list_new(GtkApplication *application);
95   - void pw3270_action_list_free(Pw3270ActionList *action_list);
96 102 void pw3270_action_view_set_actions(GtkWidget *view, Pw3270ActionList *list);
  103 + void pw3270_action_view_order_by_label(GtkWidget *view);
97 104 void pw3270_action_view_move_selected(GtkWidget *from, GtkWidget *to);
98   - void pw3270_action_view_append(GtkWidget *widget, const gchar *label, GdkPixbuf *pixbuf, const gchar *action_name, gint flags);
  105 + void pw3270_action_view_append(GtkWidget *widget, const gchar *label, GdkPixbuf *pixbuf, const gchar *action_name, const PW3270ActionViewFlag flags);
99 106 gchar * pw3270_action_view_get_action_names(GtkWidget *widget);
  107 + GtkWidget * pw3270_action_view_move_button_new(GtkWidget *from, GtkWidget *to, const gchar *icon_name);
100 108  
  109 + Pw3270ActionList * pw3270_action_list_new(GtkApplication *application);
  110 + Pw3270ActionList * pw3270_action_list_append(Pw3270ActionList *action_list, const gchar *label, GdkPixbuf *pixbuf, const gchar *action_name, const PW3270ActionViewFlag flags);
101 111 Pw3270ActionList * pw3270_action_list_move_action(Pw3270ActionList *action_list, const gchar *action_name, GtkWidget *view);
  112 + void pw3270_action_list_free(Pw3270ActionList *action_list);
102 113  
103 114 //
104 115 // Tools
... ... @@ -109,8 +120,8 @@
109 120  
110 121 GdkPixbuf * g_action_get_pixbuf(GAction *action, GtkIconSize icon_size, GtkIconLookupFlags flags);
111 122  
112   - GtkWidget * gtk_button_new_from_action(GAction *action, GtkIconSize icon_size);
113   - GtkToolItem * gtk_tool_button_new_from_action(GAction *action, GtkIconSize icon_size);
  123 + GtkWidget * gtk_button_new_from_action(GAction *action, GtkIconSize icon_size, gboolean symbolic);
  124 + GtkToolItem * gtk_tool_button_new_from_action(GAction *action, GtkIconSize icon_size, gboolean symbolic);
114 125  
115 126 G_END_DECLS
116 127  
... ...
src/include/pw3270/application.h
... ... @@ -73,6 +73,10 @@
73 73  
74 74 // Plugins
75 75 void pw3270_application_plugin_foreach(GApplication *app, GFunc func, gpointer user_data);
  76 +
  77 + /// @brief Call plugin method.
  78 + void pw3270_application_plugin_call(GApplication *app, const gchar *method, gpointer user_data);
  79 +
76 80 GSList * pw3270_application_get_plugins(GApplication *app);
77 81  
78 82 // Tools
... ... @@ -84,6 +88,10 @@
84 88 void pw3270_application_print_copy_activated(GAction *action, GVariant *parameter, GtkWidget *terminal);
85 89 void pw3270_application_save_copy_activated(GAction *action, GVariant *parameter, GtkWidget *terminal);
86 90  
  91 + // Settings
  92 + GtkWidget * pw3270_header_settings_new();
  93 +
  94 +
87 95 G_END_DECLS
88 96  
89 97  
... ...
src/include/pw3270/settings.h
... ... @@ -36,6 +36,7 @@
36 36 #endif // _WIN32
37 37  
38 38 #include <gtk/gtk.h>
  39 + #include <pw3270/actions.h>
39 40  
40 41 G_BEGIN_DECLS
41 42  
... ... @@ -87,8 +88,23 @@
87 88 typedef struct _PW3270SettingsDialogClass PW3270SettingsDialogClass;
88 89  
89 90 GType PW3270SettingsDialog_get_type(void);
90   - GtkWidget * pw3270_settings_dialog_new(GAction *action);
  91 + GtkWidget * pw3270_settings_dialog_new(GAction *action, gboolean has_subtitle);
91 92  
92 93 G_END_DECLS
93 94  
  95 +/*--[ PW3270 Action List Editor ]--------------------------------------------------------------------*/
  96 +
  97 + #define GTK_TYPE_PW3270_SETTINGS_ACTIONS (PW3270SettingsActions_get_type())
  98 +
  99 + typedef struct _PW3270SettingsActions PW3270SettingsActions;
  100 + typedef struct _PW3270SettingsActionsClass PW3270SettingsActionsClass;
  101 +
  102 + GType PW3270SettingsActions_get_type(void);
  103 + GtkWidget * pw3270_settings_actions_new();
  104 + Pw3270ActionList * pw3270_settings_action_set(GtkWidget *widget, Pw3270ActionList *available, const gchar *value);
  105 + gchar * pw3270_settings_action_get(GtkWidget *widget);
  106 +
  107 + G_END_DECLS
  108 +
  109 +
94 110 #endif // V3270SETTINGS_H_INCLUDED
... ...
src/include/pw3270/toolbar.h
... ... @@ -66,9 +66,11 @@
66 66  
67 67 void pw3270_toolbar_set_style(GtkToolbar *toolbar, GtkToolbarStyle style);
68 68 void pw3270_toolbar_set_icon_size(GtkToolbar *toolbar, GtkIconSize icon_size);
  69 + void pw3270_toolbar_set_icon_type(GtkToolbar *toolbar, gint icon_type);
69 70  
70 71 GtkToolbarStyle pw3270_toolbar_get_style(GtkToolbar *toolbar);
71 72 GtkIconSize pw3270_toolbar_get_icon_size(GtkToolbar *toolbar);
  73 + gint pw3270_toolbar_get_icon_type(GtkToolbar *toolbar);
72 74  
73 75 G_END_DECLS
74 76  
... ...
src/include/v3270/keyfile.h 0 → 100644
... ... @@ -0,0 +1,68 @@
  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 +/**
  31 + * @brief Declares the v3270 keyfile object.
  32 + *
  33 + */
  34 +
  35 +#ifndef V3270_KEYFILE_H_INCLUDED
  36 +
  37 + #define V3270_KEYFILE_H_INCLUDED
  38 +
  39 + #include <glib.h>
  40 +
  41 + G_BEGIN_DECLS
  42 +
  43 + typedef struct _V3270KeyFile V3270KeyFile;
  44 +
  45 + gchar * v3270_keyfile_get_default_filename(void);
  46 + gchar * v3270_key_file_get_default_path(GtkWidget *terminal);
  47 +
  48 + V3270KeyFile * v3270_key_file_open(GtkWidget *terminal, const gchar *name, GError **error);
  49 + void v3270_key_file_close(GtkWidget *terminal);
  50 +
  51 + void v3270_key_file_save(GtkWidget *terminal, GError **error);
  52 + void v3270_key_file_save_to_file(GtkWidget * terminal, const gchar *filename, GError **error);
  53 +
  54 + /// @brief Get current key filename
  55 + const gchar * v3270_key_file_get_filename(GtkWidget *terminal);
  56 +
  57 + /// @brief Build a writable key filename
  58 + gchar * v3270_key_file_build_filename(GtkWidget *terminal);
  59 +
  60 + GKeyFile * v3270_key_file_get(GtkWidget *terminal);
  61 +
  62 + gboolean v3270_key_file_can_write(GtkWidget *widget);
  63 +
  64 + void v3270_key_file_set_boolean(GtkWidget *terminal, const gchar *group_name, const gchar *key, gboolean value);
  65 +
  66 + G_END_DECLS
  67 +
  68 +#endif // PW3270_H_INCLUDED
... ...
src/main/main.c
... ... @@ -94,6 +94,7 @@ int main (int argc, char **argv) {
94 94 {
95 95 g_autofree gchar * appdir = g_win32_get_package_installation_directory_of_module(NULL);
96 96 g_autofree gchar * locdir = g_build_filename(appdir,"locale",NULL);
  97 + debug("Locale from \"%s\"\n",locdir);
97 98 bindtextdomain( PACKAGE_NAME, locdir );
98 99 }
99 100 #endif // _WIN32
... ...
src/main/windows/resources.rc.in
... ... @@ -16,7 +16,7 @@ BEGIN
16 16 VALUE "CompanyName", "Banco do Brasil S/A.\0"
17 17 VALUE "FileVersion", "@WIN32_VERSION@\0"
18 18 VALUE "LegalCopyright", "(C) 2017 Banco do Brasil S/A. All Rights Reserved\0"
19   - VALUE "OriginalFilename", "@APPLICATION_NAME@.exe_NAME@.exe\0""
  19 + VALUE "OriginalFilename", "@PRODUCT_NAME@.exe_NAME@.exe\0""
20 20 VALUE "ProductName", "@PRODUCT_NAME@\0"
21 21 VALUE "ProductVersion", "@PACKAGE_MAJOR_VERSION@.@PACKAGE_MINOR_VERSION@.@PACKAGE_MAJOR_RELEASE@.@PACKAGE_MINOR_RELEASE@\0"
22 22 END
... ...
src/objects/actions/button.c
... ... @@ -35,14 +35,19 @@
35 35 #include "private.h"
36 36 #include <pw3270/actions.h>
37 37  
38   - GtkWidget * gtk_button_new_from_action(GAction *action, GtkIconSize icon_size) {
  38 + GtkWidget * gtk_button_new_from_action(GAction *action, GtkIconSize icon_size, gboolean symbolic) {
39 39  
40 40 if(!action)
41 41 return NULL;
42 42  
43 43 g_autofree gchar * icon_name = g_action_get_icon_name(action);
44   - if(icon_name)
  44 + if(icon_name) {
  45 + if(symbolic && !strstr(icon_name,"-symbolic")) {
  46 + g_autofree gchar * name = g_strconcat(icon_name,"-symbolic",NULL);
  47 + return gtk_button_new_from_icon_name(name,icon_size);
  48 + }
45 49 return gtk_button_new_from_icon_name(icon_name,icon_size);
  50 + }
46 51  
47 52 GdkPixbuf * pixbuf = g_action_get_pixbuf(action, GTK_ICON_SIZE_BUTTON, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
48 53  
... ... @@ -62,7 +67,7 @@
62 67 return NULL;
63 68 }
64 69  
65   - GtkToolItem * gtk_tool_button_new_from_action(GAction *action, GtkIconSize icon_size) {
  70 + GtkToolItem * gtk_tool_button_new_from_action(GAction *action, GtkIconSize icon_size, gboolean symbolic) {
66 71  
67 72 if(!action)
68 73 return NULL;
... ... @@ -75,14 +80,18 @@
75 80 }
76 81  
77 82 g_autofree gchar * icon_name = g_action_get_icon_name(action);
78   -// debug("%s(%s).icon_name=%s",__FUNCTION__,g_action_get_name(action),icon_name);
79 83  
80 84 if(icon_name) {
81 85  
82 86 // Has icon name
83 87 GtkToolItem * item = gtk_tool_button_new(NULL,label);
84 88  
85   - gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item),icon_name);
  89 + if(symbolic && !strstr(icon_name,"-symbolic")) {
  90 + g_autofree gchar * symbolic_name = g_strconcat(icon_name,"-symbolic",NULL);
  91 + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item),symbolic_name);
  92 + } else {
  93 + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item),icon_name);
  94 + }
86 95  
87 96 if(tooltip)
88 97 gtk_widget_set_tooltip_markup(GTK_WIDGET(item),tooltip);
... ...
src/objects/actions/save.c
... ... @@ -34,21 +34,47 @@
34 34  
35 35 #include "private.h"
36 36 #include <v3270.h>
  37 + #include <v3270/keyfile.h>
37 38 #include <pw3270.h>
38 39 #include <pw3270/application.h>
39   -
  40 + #include <v3270/tools.h>
  41 + #include <v3270/settings.h>
40 42  
41 43 static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
42 44 static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
43 45  
44   - GAction * pw3270_action_save_session_as_new(void) {
  46 + static const struct Entry {
  47 +
  48 + const gchar *label;
  49 + const gchar *tooltip;
  50 + const gint width;
  51 +
  52 + } entries[] = {
  53 +
  54 + // 0 = Session name
  55 + {
  56 + .label = N_("Session name"),
  57 + .tooltip = N_("The session name used in the window/tab title (empty for default)"),
  58 + .width = 15,
  59 + },
  60 +
  61 + // 1 = Session file
  62 + {
  63 + .label = N_("Session file"),
  64 + .tooltip = N_("The file to save the current session preferences"),
  65 + .width = 40,
  66 + }
  67 +
  68 + };
  69 +
  70 + GAction * pw3270_action_save_session_preferences_new(void) {
45 71  
46 72 V3270SimpleAction * action = v3270_dialog_action_new(factory);
47 73  
48   - action->name = "save.session.as";
49   - action->label = _("Save As");
  74 + action->name = "save.session.preferences";
  75 + action->label = _("Save session preferences");
50 76 action->icon_name = "document-save-as";
51   - action->tooltip = _("Save session properties");
  77 + action->tooltip = _("Save current session preferences to file");
52 78  
53 79 return G_ACTION(action);
54 80  
... ... @@ -56,41 +82,119 @@
56 82  
57 83 GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
58 84  
  85 + // Create dialog
  86 + gboolean use_header;
  87 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  88 +
59 89 GtkWidget * dialog =
60   - gtk_file_chooser_dialog_new(
61   - action->tooltip,
62   - GTK_WINDOW(gtk_widget_get_toplevel(terminal)),
63   - GTK_FILE_CHOOSER_ACTION_SAVE,
64   - _("Save"), GTK_RESPONSE_OK,
65   - _("Cancel"),GTK_RESPONSE_CANCEL,
66   - NULL
67   - );
  90 + GTK_WIDGET(g_object_new(
  91 + GTK_TYPE_DIALOG,
  92 + "use-header-bar", (use_header ? 1 : 0),
  93 + NULL
  94 + ));
  95 +
68 96  
69 97 gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
70   - gtk_file_chooser_set_pw3270_filters(GTK_FILE_CHOOSER(dialog));
  98 + gtk_window_set_title(GTK_WINDOW(dialog),action->label);
  99 +
  100 + gtk_dialog_add_buttons(
  101 + GTK_DIALOG(dialog),
  102 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  103 + _("_Save"), GTK_RESPONSE_APPLY,
  104 + NULL
  105 + );
  106 +
  107 +
  108 + // Create entry fields
  109 + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
  110 + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
  111 + debug("Dialog=%p inputs=%p",dialog,inputs);
  112 +
  113 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  114 +
  115 + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
  116 +
  117 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  118 + gtk_container_set_border_width(GTK_CONTAINER(grid),18);
  119 + gtk_grid_set_row_spacing(GTK_GRID(grid),6);
  120 + gtk_grid_set_column_spacing(GTK_GRID(grid),12);
  121 +
  122 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  123 + // gtk_box_set_spacing(GTK_BOX(content_area),18);
  124 +
  125 + size_t ix;
  126 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  127 +
  128 + GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
  129 + gtk_label_set_xalign(GTK_LABEL(label),1);
  130 + gtk_grid_attach(grid,label,0,ix,1,1);
  131 +
  132 + inputs[ix] = gtk_entry_new();
  133 +
  134 + if(entries[ix].tooltip) {
  135 + gtk_widget_set_tooltip_markup(GTK_WIDGET(inputs[ix]),gettext(entries[ix].tooltip));
  136 + }
  137 +
  138 + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
  139 + gtk_widget_set_hexpand(inputs[ix],FALSE);
  140 + gtk_widget_set_vexpand(inputs[ix],FALSE);
  141 +
  142 + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
  143 +
  144 + }
  145 +
  146 + {
  147 + g_autofree gchar * session_filename = v3270_key_file_build_filename(terminal);
  148 + gtk_entry_set_text(GTK_ENTRY(inputs[1]),session_filename);
  149 +
  150 + gtk_entry_bind_to_filechooser(
  151 + inputs[1],
  152 + GTK_FILE_CHOOSER_ACTION_SAVE,
  153 + _("Save session preferences"),
  154 + NULL,
  155 + "*.3270",
  156 + _("3270 session files")
  157 + );
71 158  
72   - if(terminal) {
73   - const gchar * current_file = v3270_get_session_filename(terminal);
74   - if(current_file && g_file_test(current_file,G_FILE_TEST_IS_REGULAR) && !g_str_has_prefix(current_file,g_get_user_config_dir()))
75   - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),current_file);
76 159 }
77 160  
78 161 g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
79 162  
80   - gtk_widget_show_all(dialog);
  163 + gtk_widget_show_all(GTK_WIDGET(grid));
81 164 return dialog;
  165 +
82 166 }
83 167  
84 168 void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
85 169  
86   - debug("%s(%d)",__FUNCTION__,response_id);
  170 + if(response_id == GTK_RESPONSE_APPLY) {
87 171  
88   - g_autofree gchar * filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
  172 + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
  173 + gtk_widget_hide(dialog);
89 174  
90   - gtk_widget_destroy(dialog);
  175 + GError * error = NULL;
  176 + v3270_key_file_save_to_file(
  177 + terminal,
  178 + gtk_entry_get_text(GTK_ENTRY(inputs[1])),
  179 + &error
  180 + );
  181 +
  182 + if(error) {
  183 +
  184 + g_message("%s",error->message);
  185 + g_error_free(error);
  186 +
  187 + } else {
  188 +
  189 + // Set session name (after save to avoid changes on the old session file).
  190 + v3270_set_session_name(terminal,gtk_entry_get_text(GTK_ENTRY(inputs[0])));
  191 + v3270_emit_save_settings(terminal,NULL);
  192 +
  193 + }
91 194  
92   - if(response_id == GTK_RESPONSE_OK) {
93   - v3270_set_session_filename(terminal, filename);
94 195 }
95 196  
  197 +
  198 + gtk_widget_destroy(dialog);
  199 +
96 200 }
... ...
src/objects/actions/view.c
... ... @@ -45,9 +45,10 @@
45 45 };
46 46  
47 47 struct ListElement {
48   - GAction * action;
  48 +// GAction * action;
49 49 GdkPixbuf * pixbuf;
50   - gchar name[1];
  50 + gchar * action_name;
  51 + gchar * action_label;
51 52 };
52 53  
53 54 static void list_element_free(struct ListElement *element);
... ... @@ -106,7 +107,7 @@
106 107 return view;
107 108 }
108 109  
109   - void pw3270_action_view_append(GtkWidget *widget, const gchar *label, GdkPixbuf *pixbuf, const gchar *action_name, gint flags) {
  110 + void pw3270_action_view_append(GtkWidget *widget, const gchar *label, GdkPixbuf *pixbuf, const gchar *action_name, PW3270ActionViewFlag flags) {
110 111  
111 112 GtkListStore * store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget)));
112 113  
... ... @@ -118,68 +119,38 @@
118 119 COLUMN_PIXBUF, pixbuf,
119 120 COLUMN_LABEL, label,
120 121 COLUMN_ACTION_NAME, action_name,
121   - COLUMN_FLAGS, flags,
  122 + COLUMN_FLAGS, (gint) flags,
122 123 -1
123 124 );
124 125  
125 126  
126 127 }
127 128  
128   - static void pw3270_action_view_append_element(GtkListStore * store, struct ListElement * element) {
129   -
130   - size_t ix;
131   -
132   - struct Properties {
133   - const gchar * name;
134   - GType g_type;
135   - GValue value;
136   - } properties[] = {
137   - {
138   - .name = "label",
139   - .g_type = G_TYPE_STRING,
140   - .value = G_VALUE_INIT
141   - }
142   - };
143   -
144   - for(ix = 0; ix < G_N_ELEMENTS(properties); ix++) {
145   -
146   - g_value_init(&properties[ix].value, properties[ix].g_type);
147   - g_object_get_property(G_OBJECT(element->action), properties[ix].name, &properties[ix].value);
148   -
149   - }
150   -
151   - // Remove "_"
152   - g_autofree gchar * label = g_strdup(g_value_get_string(&properties[0].value));
  129 + void pw3270_action_view_order_by_label(GtkWidget *view) {
153 130  
154   - if(label) {
  131 + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(view),FALSE);
155 132  
156   - gchar *from, *to;
157   -
158   - for(from=to=label;*from;from++) {
159   - if(*from != '_') {
160   - *(to++) = *from;
161   - }
162   - }
163   - *to = 0;
  133 + gtk_tree_sortable_set_sort_column_id(
  134 + GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(view))),
  135 + COLUMN_LABEL,
  136 + GTK_SORT_ASCENDING
  137 + );
  138 + }
164 139  
165   - }
  140 + static void pw3270_action_view_append_element(GtkListStore * store, struct ListElement * element) {
166 141  
167 142 GtkTreeIter iter;
168 143 gtk_list_store_append(store, &iter);
169 144 gtk_list_store_set(
170 145 store,
171 146 &iter,
172   - COLUMN_PIXBUF, element->pixbuf,
173   - COLUMN_LABEL, (label ? label : g_action_get_name(element->action)),
174   - COLUMN_ACTION_NAME, element->name,
175   - COLUMN_FLAGS, 3,
  147 + COLUMN_PIXBUF, element->pixbuf,
  148 + COLUMN_LABEL, element->action_label,
  149 + COLUMN_ACTION_NAME, element->action_name,
  150 + COLUMN_FLAGS, (gint) PW3270_ACTION_VIEW_ALLOW_MOVE,
176 151 -1
177 152 );
178 153  
179   - for(ix = 0; ix < G_N_ELEMENTS(properties); ix++) {
180   - g_value_unset(&properties[ix].value);
181   - }
182   -
183 154 }
184 155  
185 156 Pw3270ActionList * pw3270_action_list_move_action(Pw3270ActionList *action_list, const gchar *action_name, GtkWidget *view) {
... ... @@ -190,8 +161,7 @@
190 161 while(item) {
191 162  
192 163 struct ListElement * element = (struct ListElement *) item->data;
193   -
194   - if(!g_ascii_strcasecmp(action_name,element->name)) {
  164 + if(!g_ascii_strcasecmp(action_name,element->action_name)) {
195 165  
196 166 pw3270_action_view_append_element(store, element);
197 167 list_element_free(element);
... ... @@ -219,36 +189,38 @@
219 189  
220 190 }
221 191  
222   - static GSList * append_action(GSList * list, const gchar *type, GAction *action) {
  192 + static GSList * append_action(GSList * list, const gchar *prefix, GAction *action) {
223 193  
224 194 if(!action)
225 195 return list;
226 196  
227   - if(!g_object_class_find_property(G_OBJECT_GET_CLASS(action),"label")) {
228   - debug("Action \"%s\": Doesn't have a label",g_action_get_name(action));
229   - return list;
230   - }
231   -
232 197 GdkPixbuf * pixbuf = g_action_get_pixbuf(action, GTK_ICON_SIZE_MENU, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
233 198 if(!pixbuf) {
234 199 debug("Action \"%s\": Doesn't have a pixbuf",g_action_get_name(action));
235 200 return list;
236 201 }
237 202  
238   - const gchar *name = g_action_get_name(action);
239   -
240   - struct ListElement * element = (struct ListElement *) g_malloc0(sizeof(struct ListElement) + strlen(type) + strlen(name));
  203 + g_autofree gchar *action_name = g_strconcat(prefix,".",g_action_get_name(action),NULL);
241 204  
242   - strcpy(element->name,type);
243   - strcat(element->name,name);
  205 + GValue value = G_VALUE_INIT;
  206 + g_value_init(&value, G_TYPE_STRING);
  207 + g_object_get_property(G_OBJECT(action),"label",&value);
244 208  
245   - element->action = action;
  209 + const gchar * label = g_value_get_string(&value);
  210 + if(!(label && *label))
  211 + label = g_action_get_name(action);
246 212  
247   - element->pixbuf = pixbuf;
248   - g_object_ref_sink(G_OBJECT(element->pixbuf));
  213 + list = pw3270_action_list_append(
  214 + list,
  215 + label,
  216 + pixbuf,
  217 + action_name,
  218 + PW3270_ACTION_VIEW_ALLOW_MOVE
  219 + );
249 220  
250   - return g_slist_prepend(list,element);
  221 + g_value_unset(&value);
251 222  
  223 + return list;
252 224 }
253 225  
254 226 Pw3270ActionList * pw3270_action_list_new(GtkApplication *application) {
... ... @@ -262,7 +234,7 @@
262 234  
263 235 action_names = g_action_group_list_actions(G_ACTION_GROUP(application));
264 236 for(ix = 0; action_names[ix];ix++) {
265   - list = append_action(list,"app.",g_action_map_lookup_action(G_ACTION_MAP(application),action_names[ix]));
  237 + list = append_action(list,"app",g_action_map_lookup_action(G_ACTION_MAP(application),action_names[ix]));
266 238 }
267 239 g_strfreev(action_names);
268 240  
... ... @@ -274,7 +246,7 @@
274 246 // Get window actions.
275 247 action_names = g_action_group_list_actions(G_ACTION_GROUP(window));
276 248 for(ix = 0; action_names[ix];ix++) {
277   - list = append_action(list,"win.",g_action_map_lookup_action(G_ACTION_MAP(window),action_names[ix]));
  249 + list = append_action(list,"win",g_action_map_lookup_action(G_ACTION_MAP(window),action_names[ix]));
278 250 }
279 251 g_strfreev(action_names);
280 252  
... ... @@ -283,6 +255,32 @@
283 255 return (Pw3270ActionList *) list;
284 256 }
285 257  
  258 + Pw3270ActionList * pw3270_action_list_append(Pw3270ActionList *action_list, const gchar *label, GdkPixbuf *pixbuf, const gchar *action_name, const PW3270ActionViewFlag flags) {
  259 +
  260 + struct ListElement * element = (struct ListElement *)
  261 + g_malloc0(
  262 + sizeof(struct ListElement)
  263 + + strlen(action_name)
  264 + + strlen(label)
  265 + + 3
  266 + );
  267 +
  268 + if(pixbuf) {
  269 + element->pixbuf = pixbuf;
  270 + g_object_ref_sink(G_OBJECT(element->pixbuf));
  271 + }
  272 +
  273 + element->action_name = (char *) (element+1);
  274 + strcpy(element->action_name,action_name);
  275 +
  276 + element->action_label = element->action_name + strlen(element->action_name) + 1;
  277 + strcpy(element->action_label,label);
  278 +
  279 + return (Pw3270ActionList *) g_slist_prepend((GSList *) action_list, element);
  280 +
  281 +
  282 + };
  283 +
286 284 void list_element_free(struct ListElement *element) {
287 285  
288 286 if(element->pixbuf) {
... ... @@ -338,7 +336,7 @@
338 336 gint flags = g_value_get_int(&vFlags);
339 337 g_value_unset(&vFlags);
340 338  
341   - if(flags & 1) {
  339 + if(flags & PW3270_ACTION_VIEW_FLAG_ALLOW_ADD) {
342 340  
343 341 // Add on target widget.
344 342 GValue pixbuf = G_VALUE_INIT;
... ... @@ -369,7 +367,7 @@
369 367  
370 368 }
371 369  
372   - if(flags & 2) {
  370 + if(flags & PW3270_ACTION_VIEW_ALLOW_REMOVE) {
373 371  
374 372 // Remove from source widget.
375 373 gtk_list_store_remove(GTK_LIST_STORE(fromModel), &iter);
... ... @@ -411,3 +409,70 @@
411 409 return g_string_free(str,FALSE);
412 410 }
413 411  
  412 + static void check_4_sensitive(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gboolean *sensitive) {
  413 +
  414 + GValue value = { 0, };
  415 + gtk_tree_model_get_value(model,iter,COLUMN_FLAGS,&value);
  416 +
  417 + if(!(g_value_get_int(&value) & PW3270_ACTION_VIEW_FLAG_ALLOW_ADD))
  418 + *sensitive = FALSE;
  419 +
  420 + g_value_unset(&value);
  421 +
  422 + }
  423 +
  424 + static void selection_changed(GtkTreeSelection *selection, GtkWidget *button) {
  425 +
  426 + if(!gtk_tree_selection_count_selected_rows(selection)) {
  427 + gtk_widget_set_sensitive(button,FALSE);
  428 + return;
  429 + }
  430 +
  431 + gboolean sensitive = TRUE;
  432 +
  433 + // Scan selected rows
  434 + gtk_tree_selection_selected_foreach(selection,(GtkTreeSelectionForeachFunc) check_4_sensitive,&sensitive);
  435 + gtk_widget_set_sensitive(button,sensitive);
  436 +
  437 + }
  438 +
  439 + struct MoveData {
  440 + GtkWidget *from;
  441 + GtkWidget *to;
  442 + };
  443 +
  444 + static void move_clicked(GtkButton G_GNUC_UNUSED(*button), struct MoveData *args) {
  445 + pw3270_action_view_move_selected(args->from,args->to);
  446 + }
  447 +
  448 + GtkWidget * pw3270_action_view_move_button_new(GtkWidget *from, GtkWidget *to, const gchar *icon_name) {
  449 +
  450 + GtkWidget * button = gtk_button_new_from_icon_name(icon_name,GTK_ICON_SIZE_DND);
  451 +
  452 + struct MoveData * data = g_new0(struct MoveData,1);
  453 + data->from = from;
  454 + data->to = to;
  455 + g_object_set_data_full(G_OBJECT(button),"move-control-data",data,g_free);
  456 +
  457 + gtk_widget_set_focus_on_click(button,FALSE);
  458 + gtk_button_set_relief(GTK_BUTTON(button),GTK_RELIEF_NONE);
  459 + gtk_widget_set_sensitive(button,FALSE);
  460 + gtk_widget_set_hexpand(button,FALSE);
  461 + gtk_widget_set_vexpand(button,FALSE);
  462 +
  463 + g_signal_connect(
  464 + gtk_tree_view_get_selection(GTK_TREE_VIEW(from)),
  465 + "changed",
  466 + G_CALLBACK(selection_changed),
  467 + button
  468 + );
  469 +
  470 + g_signal_connect(
  471 + button,
  472 + "clicked",
  473 + G_CALLBACK(move_clicked),
  474 + data
  475 + );
  476 +
  477 + return button;
  478 + }
... ...
src/objects/application/actions/about.c
... ... @@ -33,22 +33,6 @@
33 33  
34 34 static GtkWidget * factory(PW3270Action G_GNUC_UNUSED(*action), GtkApplication G_GNUC_UNUSED(*application)) {
35 35  
36   - /*
37   - static const gchar *license =
38   - N_( "This program is free software; you can redistribute it and/or "
39   - "modify it under the terms of the GNU General Public License as "
40   - "published by the Free Software Foundation; either version 2 of the "
41   - "License, or (at your option) any later version.\n\n"
42   - "This program is distributed in the hope that it will be useful, "
43   - "but WITHOUT ANY WARRANTY; without even the implied warranty of "
44   - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
45   - "GNU General Public License for more details.\n\n"
46   - "You should have received a copy of the GNU General Public License "
47   - "along with this program; if not, write to the Free Software "
48   - "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 "
49   - "USA" );
50   - */
51   -
52 36 GtkAboutDialog * dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
53 37  
54 38 // Get application logo
... ... @@ -82,18 +66,37 @@
82 66  
83 67 // Set version
84 68 {
  69 + g_autofree gchar * version = g_strdup_printf(
  70 + _("Version %s-%s"),
  71 + PACKAGE_VERSION,
85 72 #ifdef PACKAGE_RELEASE
86   - g_autofree gchar * version = g_strdup_printf(_("Version %s-%s"),PACKAGE_VERSION,PACKAGE_RELEASE);
  73 + PACKAGE_RELEASE
87 74 #else
88   - g_autofree gchar * version = g_strdup_printf(_("Version %s-%s"),PACKAGE_VERSION,G_STRINGIFY(BUILD_DATE));
89   -#endif // PACKAGE_REVISION
  75 + G_STRINGIFY(BUILD_DATE)
  76 +#endif // PACKAGE_RELEASE
  77 + );
90 78  
91 79 gtk_about_dialog_set_version(dialog,version);
92 80 }
93 81  
94 82 // Set comments
95 83 {
96   - g_autofree gchar * comments = g_strdup_printf(_( "3270 terminal emulator for GTK %d.%d" ),GTK_MAJOR_VERSION,GTK_MINOR_VERSION);
  84 + g_autofree gchar * comments =
  85 +
  86 + g_strdup_printf(
  87 + _( "3270 terminal emulator for %s." ),
  88 +#if defined(__MINGW64__)
  89 + _( "64 bits Windows" )
  90 +#elif defined(__MINGW32__)
  91 + _( "32 bits Windows" )
  92 +#elif defined(linux) && defined(__i386__)
  93 + _( "32 bits Linux" )
  94 +#elif defined(linux) && defined(__x86_64__)
  95 + _( "64 bits Linux" )
  96 +#else
  97 + "GTK"
  98 +#endif
  99 + );
97 100 gtk_about_dialog_set_comments(dialog, comments);
98 101 }
99 102  
... ... @@ -126,22 +129,39 @@
126 129 gtk_about_dialog_add_credit_section(dialog, _("Apple version"), apple);
127 130 gtk_about_dialog_add_credit_section (dialog, _("Contributors"), contributors);
128 131  
129   -
130 132 gtk_about_dialog_add_credit_section(dialog, _("Based on X3270 from"), references);
131 133  
132 134 }
133 135  
134 136 gtk_about_dialog_set_copyright(dialog, "Copyright © 2008 Banco do Brasil S.A." );
135 137  
136   -// gtk_about_dialog_set_license(dialog, gettext( license ) );
137   -// gtk_about_dialog_set_wrap_license(dialog,TRUE);
  138 +#ifdef _WIN32
  139 +
  140 + lib3270_autoptr(char) license = lib3270_build_data_filename(_("LICENSE"),NULL);
138 141  
  142 + if(g_file_test(license, G_FILE_TEST_IS_REGULAR)) {
  143 +
  144 + g_autofree gchar * text = NULL;
  145 +
  146 + if(g_file_get_contents(license,&text,NULL,NULL)) {
  147 + gtk_about_dialog_set_license(dialog, text );
  148 + gtk_about_dialog_set_wrap_license(dialog,TRUE);
  149 + }
  150 +
  151 + } else {
  152 + gtk_about_dialog_set_license_type(dialog,GTK_LICENSE_GPL_3_0);
  153 + }
  154 +
  155 +#else
139 156 gtk_about_dialog_set_license_type(dialog,GTK_LICENSE_GPL_3_0);
  157 +#endif // _WIN32
  158 +
  159 +// gtk_about_dialog_set_website(dialog,NC_("ProjectURL","https://portal.softwarepublico.gov.br/social/pw3270/"));
  160 +// gtk_about_dialog_set_website_label(dialog,NC_("ProjectURLLabel","Brazilian Public Software Portal" ));
140 161  
141   - gtk_about_dialog_set_website(dialog,"https://portal.softwarepublico.gov.br/social/pw3270/");
142   - gtk_about_dialog_set_website_label(dialog,_( "Brazilian Public Software Portal" ));
  162 + gtk_about_dialog_set_website(dialog,_("https://github.com/PerryWerneck/pw3270"));
  163 + gtk_about_dialog_set_website_label(dialog,_("View this project on github"));
143 164  
144   -// gtk_about_dialog_set_authors(dialog,authors);
145 165 gtk_about_dialog_set_translator_credits(dialog,_("translator-credits"));
146 166  
147 167 gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
... ... @@ -149,6 +169,13 @@
149 169 g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
150 170 gtk_widget_show_all(GTK_WIDGET(dialog));
151 171  
  172 + // Call plugins
  173 + pw3270_application_plugin_call(
  174 + g_application_get_default(),
  175 + "pw3270_plugin_set_about_dialog",
  176 + dialog
  177 + );
  178 +
152 179 return GTK_WIDGET(dialog);
153 180  
154 181 }
... ...
src/objects/application/actions/preferences.c
... ... @@ -34,14 +34,11 @@
34 34 #include <pw3270/settings.h>
35 35 #include <pw3270/toolbar.h>
36 36  
37   -
38   -// gtk_window_set_title(GTK_WINDOW(dialog),action->label);
39   -
40 37 static GtkWidget * factory(PW3270Action * action, GtkApplication *application) {
41 38  
42 39 size_t ix;
43 40 GtkWindow * window = gtk_application_get_active_window(application);
44   - GtkWidget * dialog = pw3270_settings_dialog_new(G_ACTION(action));
  41 + GtkWidget * dialog = pw3270_settings_dialog_new(G_ACTION(action),TRUE);
45 42  
46 43 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
47 44 gtk_window_set_attached_to(GTK_WINDOW(dialog), GTK_WIDGET(window));
... ... @@ -55,6 +52,16 @@
55 52 gtk_container_add(GTK_CONTAINER(dialog),pages[ix]);
56 53 }
57 54  
  55 + pw3270_application_plugin_call(
  56 + G_APPLICATION(application),
  57 + "pw3270_plugin_set_application_preferences",
  58 + dialog
  59 + );
  60 +
  61 + if(pw3270_application_get_ui_style(G_APPLICATION(application)) != PW3270_UI_STYLE_CLASSICAL){
  62 + gtk_container_add(GTK_CONTAINER(dialog),pw3270_header_settings_new());
  63 + }
  64 +
58 65 gtk_widget_show_all(dialog);
59 66  
60 67 return dialog;
... ... @@ -68,6 +75,7 @@
68 75 action->name = "preferences";
69 76 action->label = _("Application preferences");
70 77 action->icon_name = "preferences-system";
  78 + action->tooltip = _("Change the application preferences");
71 79  
72 80 return G_ACTION(action);
73 81 }
... ...
src/objects/application/actions/window.c
... ... @@ -69,7 +69,7 @@
69 69 return G_ACTION(action);
70 70 }
71 71  
72   - static void new_tab_activated(GAction *action, GVariant *parameter, GtkApplication *application) {
  72 + static void new_tab_activated(GAction G_GNUC_UNUSED(*action), GVariant G_GNUC_UNUSED(*parameter), GtkApplication *application) {
73 73  
74 74 debug("%s",__FUNCTION__);
75 75 pw3270_application_window_new_tab(GTK_WIDGET(gtk_application_get_active_window(GTK_APPLICATION(application))), NULL);
... ...
src/objects/application/application.c
... ... @@ -173,13 +173,8 @@
173 173  
174 174 }
175 175  
176   -
177 176 static gboolean on_user_interface(const gchar G_GNUC_UNUSED(*option), const gchar *value, gpointer G_GNUC_UNUSED(dunno), GError **error) {
178 177  
179   - GApplication * app = g_application_get_default();
180   -
181   - debug("********************* %p",app);
182   -
183 178 g_autoptr(GSettings) app_settings = pw3270_application_settings_new();
184 179 g_autoptr(GSettings) win_settings = pw3270_application_window_settings_new();
185 180  
... ... @@ -466,6 +461,33 @@
466 461  
467 462 }
468 463  
  464 + void pw3270_application_plugin_foreach(GApplication *app, GFunc func, gpointer user_data) {
  465 +
  466 + g_return_if_fail(PW3270_IS_APPLICATION(app));
  467 +
  468 + GSList * item;
  469 + for(item = PW3270_APPLICATION(app)->plugins; item; item = g_slist_next(item)) {
  470 + func(item->data,user_data);
  471 + }
  472 +
  473 + }
  474 +
  475 + void pw3270_application_plugin_call(GApplication *app, const gchar *method, gpointer user_data) {
  476 +
  477 + g_return_if_fail(PW3270_IS_APPLICATION(app));
  478 +
  479 + int (*call)(GtkWidget *);
  480 +
  481 + GSList * item;
  482 + for(item = PW3270_APPLICATION(app)->plugins; item; item = g_slist_next(item)) {
  483 + if(g_module_symbol((GModule *) item->data, method, (gpointer *) &call)) {
  484 + call(user_data);
  485 + }
  486 + }
  487 +
  488 + }
  489 +
  490 +
469 491 GSettings * pw3270_application_settings_new() {
470 492  
471 493 GSettings *settings = NULL;
... ... @@ -510,3 +532,4 @@
510 532 g_return_val_if_fail(PW3270_IS_APPLICATION(app),NULL);
511 533 return PW3270_APPLICATION(app)->keypads;
512 534 }
  535 +
... ...
src/objects/application/open.c
... ... @@ -29,22 +29,54 @@
29 29  
30 30 #include "private.h"
31 31  
  32 + gchar * v3270_keyfile_find(const gchar *name) {
  33 + //
  34 + // It can be a session file, scans for it
  35 + //
  36 + const gchar * paths[] = {
  37 + g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS),
  38 + g_get_user_config_dir()
  39 + };
  40 +
  41 + static const gchar *subdirs[] = {
  42 + "3270",
  43 + G_STRINGIFY(PRODUCT_NAME),
  44 + PACKAGE_NAME
  45 + };
  46 +
  47 + size_t path, subdir;
  48 +
  49 + g_autofree gchar * filename = g_strconcat(name,".3270",NULL);
  50 +
  51 + for(path = 0; path < G_N_ELEMENTS(paths); path++) {
  52 +
  53 + for(subdir = 0; subdir < G_N_ELEMENTS(subdirs); subdir++) {
  54 +
  55 + gchar * fullpath = g_build_filename(paths[path],subdirs[subdir],filename,NULL);
  56 +
  57 + debug("Searching for \"%s\"",fullpath);
  58 +
  59 + if(g_file_test(fullpath,G_FILE_TEST_IS_REGULAR)) {
  60 + return fullpath;
  61 + }
  62 + g_free(fullpath);
  63 +
  64 + }
  65 + }
  66 +
  67 + return NULL;
  68 +
  69 + }
  70 +
32 71 void pw3270_application_open(GApplication *application, GFile **files, gint n_files, const gchar G_GNUC_UNUSED(*hint)) {
33 72  
34 73 GtkWidget * window = GTK_WIDGET(gtk_application_get_active_window(GTK_APPLICATION(application)));
35   -
  74 + size_t path, subdir;
36 75 gint file;
37 76  
38 77 for(file = 0; file < n_files; file++) {
39 78  
40 79 g_autofree gchar *path = g_file_get_path(files[file]);
41   - if(!window) {
42   - debug("%s: Open in new window",__FUNCTION__);
43   - window = pw3270_application_window_new(GTK_APPLICATION(application), path);
44   - } else {
45   - debug("%s: Open in new tab",__FUNCTION__);
46   - window = pw3270_application_window_new_tab(window,path);
47   - }
48 80  
49 81 if(!path) {
50 82  
... ... @@ -63,6 +95,38 @@
63 95  
64 96 }
65 97  
  98 + continue;
  99 +
  100 + }
  101 +
  102 + if(g_file_test(path,G_FILE_TEST_IS_REGULAR)) {
  103 +
  104 + // The file exists, use it.
  105 +
  106 + if(!window) {
  107 + window = pw3270_application_window_new(GTK_APPLICATION(application), path);
  108 + } else {
  109 + window = pw3270_application_window_new_tab(window,path);
  110 + }
  111 +
  112 + continue;
  113 + }
  114 +
  115 + {
  116 + g_autofree gchar * basename = g_file_get_basename(files[file]);
  117 + g_autofree gchar * filename = v3270_keyfile_find(basename);
  118 +
  119 + if(filename) {
  120 +
  121 + if(!window) {
  122 + window = pw3270_application_window_new(GTK_APPLICATION(application), filename);
  123 + } else {
  124 + window = pw3270_application_window_new_tab(window, filename);
  125 + }
  126 +
  127 + continue;
  128 + }
  129 +
66 130 }
67 131  
68 132 }
... ...
src/objects/keypad/element.c
... ... @@ -159,12 +159,12 @@
159 159  
160 160 }
161 161  
162   - static void KeypadElement_init(KeypadElement *object) {
  162 + static void KeypadElement_init(KeypadElement G_GNUC_UNUSED(*object)) {
163 163  
164 164  
165 165 }
166 166  
167   - static void get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
  167 + static void get_property(GObject *object, guint prop_id, GValue *value, GParamSpec G_GNUC_UNUSED(*pspec)) {
168 168  
169 169 KeypadElement * element = PW_KEYPAD_ELEMENT(object);
170 170  
... ... @@ -203,7 +203,7 @@
203 203  
204 204 }
205 205  
206   - static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
  206 + static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec G_GNUC_UNUSED(*pspec)) {
207 207  
208 208 KeypadElement * element = PW_KEYPAD_ELEMENT(object);
209 209  
... ...
src/objects/keypad/load.c
... ... @@ -82,7 +82,7 @@
82 82  
83 83 }
84 84  
85   - static void element_end(GMarkupParseContext *context, const gchar *element_name, GList **keypads, GError **error) {
  85 + static void element_end(GMarkupParseContext *context, const gchar *element_name, GList G_GNUC_UNUSED(**keypads), GError G_GNUC_UNUSED(**error)) {
86 86  
87 87 debug("%s(%s)",__FUNCTION__,element_name);
88 88  
... ...
src/objects/linux/savedesktopicon.c
... ... @@ -1,301 +0,0 @@
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   - /**
31   - * @brief Implement Linux version of the save desktop icon action.
32   - *
33   - */
34   -
35   - #include <v3270.h>
36   - #include <pw3270.h>
37   - #include <pw3270/application.h>
38   - #include <v3270/actions.h>
39   - #include <lib3270.h>
40   - #include <lib3270/log.h>
41   -
42   - static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
43   - static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
44   -
45   -/*
46   -
47   -[Desktop Entry]
48   -GenericName=pw3270
49   -Name=pw3270
50   -Comment=Comment
51   -Exec=/usr/bin/sisbb
52   -Icon=pw3270
53   -Terminal=false
54   -Type=Application
55   -StartupNotify=true
56   -Categories=GTK;GNOME;TerminalEmulator
57   -OnlyShowIn=GNOME;Unity
58   -X-Desktop-File-Install-Version=0.23
59   -*/
60   -
61   - static const struct _entry {
62   -
63   - const gchar * key;
64   - const gchar * label;
65   - const gchar * tooltip;
66   - gint width;
67   -// gint n_chars;
68   -
69   - } entries[] = {
70   -
71   - {
72   - .label = N_("File name"),
73   - .width = 40,
74   -// .n_chars = 40
75   - },
76   -
77   - {
78   - .key = "Name",
79   - .label = N_("Launcher name"),
80   - .width = 20,
81   -// .n_chars = 128
82   - },
83   -
84   - {
85   - .key = "GenericName",
86   - .label = N_("Generic name"),
87   - .width = 20,
88   -// .n_chars = 128
89   - },
90   -
91   - {
92   - .key = "Comment",
93   - .label = N_("Comment"),
94   - .width = 30,
95   -// .n_chars = 128
96   - }
97   -
98   - };
99   -
100   - GAction * pw3270_action_save_desktop_icon_new(void) {
101   -
102   - V3270SimpleAction * action = v3270_dialog_action_new(factory);
103   -
104   - action->name = "save.launcher";
105   - action->label = _("Save desktop icon");
106   - action->tooltip = _("Create a desktop icon for the current session");
107   -
108   - return G_ACTION(action);
109   -
110   - }
111   -
112   - GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
113   -
114   - size_t ix;
115   -
116   - gboolean use_header;
117   - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
118   -
119   - GtkWidget * dialog =
120   - GTK_WIDGET(g_object_new(
121   - GTK_TYPE_DIALOG,
122   - "use-header-bar", (use_header ? 1 : 0),
123   - NULL
124   - ));
125   -
126   -
127   - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
128   - gtk_window_set_title(GTK_WINDOW(dialog),action->label);
129   -
130   - gtk_dialog_add_buttons(
131   - GTK_DIALOG(dialog),
132   - _("_Cancel"), GTK_RESPONSE_CANCEL,
133   - _("_Save"), GTK_RESPONSE_APPLY,
134   - NULL
135   - );
136   -
137   - g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
138   -
139   - // Create entry fields
140   - GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
141   - g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
142   - debug("Dialog=%p inputs=%p",dialog,inputs);
143   -
144   - GtkGrid * grid = GTK_GRID(gtk_grid_new());
145   -
146   - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
147   -
148   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
149   - gtk_container_set_border_width(GTK_CONTAINER(grid),18);
150   - gtk_grid_set_row_spacing(GTK_GRID(grid),6);
151   - gtk_grid_set_column_spacing(GTK_GRID(grid),12);
152   -
153   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
154   - // gtk_box_set_spacing(GTK_BOX(content_area),18);
155   -
156   - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
157   -
158   - GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
159   - gtk_label_set_xalign(GTK_LABEL(label),1);
160   - gtk_grid_attach(grid,label,0,ix,1,1);
161   -
162   - inputs[ix] = gtk_entry_new();
163   - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
164   -
165   - gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
166   -// gtk_entry_set_max_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].n_chars);
167   - gtk_widget_set_hexpand(inputs[ix],FALSE);
168   - gtk_widget_set_vexpand(inputs[ix],FALSE);
169   -
170   - gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
171   -
172   - }
173   -
174   - g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP));
175   -
176   - gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);
177   -
178   - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));
179   - gtk_entry_set_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));
180   -
181   - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));
182   - gtk_entry_set_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));
183   -
184   - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));
185   - gtk_entry_set_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));
186   - gtk_entry_set_input_hints(GTK_ENTRY(inputs[3]),GTK_INPUT_HINT_SPELLCHECK);
187   -
188   - gtk_widget_show_all(GTK_WIDGET(grid));
189   - return dialog;
190   - }
191   -
192   - void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
193   -
194   - debug("%s(%d)",__FUNCTION__,response_id);
195   -
196   - if(response_id == GTK_RESPONSE_APPLY) {
197   -
198   - static const char * key_file_data =
199   - "[Desktop Entry]\n" \
200   - "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \
201   - "Terminal=false\n" \
202   - "Type=Application\n" \
203   - "StartupNotify=true\n" \
204   - "Categories=GTK;GNOME;TerminalEmulator\n" \
205   - "OnlyShowIn=GNOME;Unity\n";
206   -
207   - GError * error = NULL;
208   - size_t ix;
209   -
210   - GKeyFile * keyfile = g_key_file_new();
211   - g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL);
212   -
213   -#ifdef DEBUG
214   - {
215   - g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL);
216   - debug("\n%s\n",dbg_data);
217   - }
218   -#endif // DEBUG
219   -
220   -
221   - GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
222   - debug("dialog=%p inputs=%p",dialog,inputs);
223   -
224   - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
225   - if(entries[ix].key) {
226   - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
227   - g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix])));
228   - }
229   - }
230   -
231   - // Get session filename
232   - /*
233   - const gchar * session_file = v3270_get_session_filename(terminal);
234   -
235   - if(!session_file) {
236   -
237   - // No session file, create one.
238   -
239   - // Check for configdir
240   - g_autofree gchar * configdir = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME),"sessions",NULL);
241   - g_mkdir_with_parents(configdir,0755);
242   -
243   - // Create a base name
244   - g_autofree gchar * basename = g_path_get_basename(gtk_entry_get_text(GTK_ENTRY(inputs[0])));
245   -
246   - gchar *ptr = strrchr(basename,'.');
247   - if(ptr)
248   - *ptr = 0;
249   -
250   - ix = time(NULL);
251   - gchar * new_session_file = g_strdup_printf("%s/%s.3270",configdir,basename);
252   - while(!g_file_test(new_session_file,G_FILE_TEST_EXISTS)) {
253   - g_free(new_session_file);
254   - new_session_file = g_strdup_printf("%s/%s_%08lx.3270",configdir,basename,(unsigned long) ix++);
255   - }
256   -
257   - g_message("Saving session to %s",new_session_file);
258   - v3270_set_session_filename(terminal,new_session_file);
259   - g_free(new_session_file);
260   -
261   - }
262   - */
263   -
264   - // Get program file name
265   - // https://stackoverflow.com/questions/4517425/how-to-get-program-path
266   - {
267   - char buffer[4096];
268   - g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid());
269   -
270   - int bytes = readlink(pidfile,buffer,4095);
271   -
272   - if(bytes >= 0)
273   - buffer[bytes] = '\0';
274   -
275   - g_autofree gchar * exec_line = g_strdup_printf("%s \"%s\"",buffer,v3270_get_session_filename(terminal));
276   - g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line);
277   -
278   - }
279   -
280   - g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[0])),&error);
281   -
282   - if(error) {
283   -
284   - g_message("%s",error->message);
285   -
286   -
287   - g_error_free(error);
288   -
289   - } else {
290   -
291   - g_message("File \"%s\" was saved",gtk_entry_get_text(GTK_ENTRY(inputs[0])));
292   -
293   - }
294   -
295   -
296   - g_key_file_free(keyfile);
297   - }
298   -
299   - gtk_widget_destroy(dialog);
300   -
301   -}
src/objects/os/linux/savedesktopicon.c 0 → 100644
... ... @@ -0,0 +1,378 @@
  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 + /**
  31 + * @brief Implement Linux version of the save desktop icon action.
  32 + *
  33 + */
  34 +
  35 + #include <v3270.h>
  36 + #include <pw3270.h>
  37 + #include <pw3270/application.h>
  38 + #include <v3270/actions.h>
  39 + #include <v3270/keyfile.h>
  40 + #include <v3270/settings.h>
  41 + #include <lib3270.h>
  42 + #include <lib3270/log.h>
  43 + #include <lib3270/properties.h>
  44 + #include <v3270/tools.h>
  45 +
  46 + static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
  47 + static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
  48 +
  49 + static const struct _entry {
  50 +
  51 + const gchar * key;
  52 + const gchar * label;
  53 + const gchar * tooltip;
  54 + const gchar * default_value;
  55 + gint margin_top;
  56 + gint width;
  57 +
  58 + } entries[] = {
  59 +
  60 + // 0 = Shortcut name
  61 + {
  62 + .key = "Name",
  63 + .label = N_("Shortcut name"),
  64 + .default_value = G_STRINGIFY(PRODUCT_NAME),
  65 + .width = 20,
  66 + },
  67 +
  68 + // 1 = Shortcut file
  69 + {
  70 + .label = N_("Shortcut file"),
  71 + .tooltip = N_("Path for the new shortcut"),
  72 + .width = 40,
  73 + },
  74 +
  75 + // 2 = Session name
  76 + {
  77 + .label = N_("Session name"),
  78 + .margin_top = 12,
  79 + .tooltip = N_("The session name used in the window/tab title (empty for default)"),
  80 + .width = 15,
  81 + },
  82 +
  83 + // 3 = Session file
  84 + {
  85 + .label = N_("Session file"),
  86 + .tooltip = N_("The file with the session preferences for this shortcut"),
  87 + .width = 40,
  88 + },
  89 +
  90 + // 4 = Generic name.
  91 + {
  92 + .key = "GenericName",
  93 + .margin_top = 12,
  94 + .label = N_("Generic name"),
  95 + .default_value = G_STRINGIFY(PRODUCT_NAME),
  96 + .width = 20,
  97 + },
  98 +
  99 + {
  100 + .key = "Comment",
  101 + .label = N_("Comment"),
  102 + .default_value = N_("IBM 3270 Terminal emulator"),
  103 + .width = 30,
  104 + }
  105 +
  106 + };
  107 +
  108 + GAction * pw3270_action_save_desktop_icon_new(void) {
  109 +
  110 + V3270SimpleAction * action = v3270_dialog_action_new(factory);
  111 +
  112 + action->name = "save.launcher";
  113 + action->label = _("Save session shortcut");
  114 + action->tooltip = _("Create shortcut for the current session");
  115 +
  116 + return G_ACTION(action);
  117 +
  118 + }
  119 +
  120 + /*
  121 + static gchar * get_filename(GtkWidget *terminal) {
  122 +
  123 + g_autofree gchar * defname = v3270_keyfile_get_default_filename();
  124 + const gchar * current = v3270_key_file_get_filename(terminal);
  125 +
  126 + // If is not the default name, return it.
  127 + if(strcmp(defname,current)) {
  128 + return g_strdup(current);
  129 + }
  130 +
  131 + // It's the default one, create a new one on the user_config dir
  132 + g_autofree gchar * config_path = v3270_key_file_get_default_path(terminal);
  133 +
  134 + // Use the hostname
  135 + const char * hostname = lib3270_host_get_name(v3270_get_session(terminal));
  136 + if(!hostname) {
  137 + hostname = G_STRINGIFY(PRODUCT_NAME);
  138 + }
  139 +
  140 + // Build the filename
  141 + gchar *filename = g_strconcat(config_path,G_DIR_SEPARATOR_S,hostname,".3270",NULL);
  142 +
  143 + unsigned int index = 0;
  144 + while(g_file_test(filename,G_FILE_TEST_EXISTS)) {
  145 + g_free(filename);
  146 + filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.%u.3270",config_path,hostname,++index);
  147 + }
  148 +
  149 + return filename;
  150 +
  151 + }
  152 + */
  153 +
  154 + GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
  155 +
  156 + size_t ix;
  157 +
  158 + gboolean use_header;
  159 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  160 +
  161 + GtkWidget * dialog =
  162 + GTK_WIDGET(g_object_new(
  163 + GTK_TYPE_DIALOG,
  164 + "use-header-bar", (use_header ? 1 : 0),
  165 + NULL
  166 + ));
  167 +
  168 +
  169 + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
  170 + gtk_window_set_title(GTK_WINDOW(dialog),action->label);
  171 +
  172 + gtk_dialog_add_buttons(
  173 + GTK_DIALOG(dialog),
  174 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  175 + _("_Save"), GTK_RESPONSE_APPLY,
  176 + NULL
  177 + );
  178 +
  179 + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
  180 +
  181 + // Create entry fields
  182 + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
  183 + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
  184 + debug("Dialog=%p inputs=%p",dialog,inputs);
  185 +
  186 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  187 +
  188 + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
  189 +
  190 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  191 + gtk_container_set_border_width(GTK_CONTAINER(grid),18);
  192 + gtk_grid_set_row_spacing(GTK_GRID(grid),6);
  193 + gtk_grid_set_column_spacing(GTK_GRID(grid),12);
  194 +
  195 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  196 + // gtk_box_set_spacing(GTK_BOX(content_area),18);
  197 +
  198 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  199 +
  200 + GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
  201 + gtk_label_set_xalign(GTK_LABEL(label),1);
  202 + gtk_grid_attach(grid,label,0,ix,1,1);
  203 +
  204 + inputs[ix] = gtk_entry_new();
  205 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  206 +
  207 + if(entries[ix].margin_top) {
  208 + gtk_widget_set_margin_top(label,entries[ix].margin_top);
  209 + gtk_widget_set_margin_top(inputs[ix],entries[ix].margin_top);
  210 + }
  211 +
  212 + if(entries[ix].default_value) {
  213 + gtk_entry_set_text(GTK_ENTRY(inputs[ix]),gettext(entries[ix].default_value));
  214 + }
  215 +
  216 + if(entries[ix].tooltip) {
  217 + gtk_widget_set_tooltip_markup(GTK_WIDGET(inputs[ix]),gettext(entries[ix].tooltip));
  218 + }
  219 +
  220 + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
  221 + gtk_widget_set_hexpand(inputs[ix],FALSE);
  222 + gtk_widget_set_vexpand(inputs[ix],FALSE);
  223 +
  224 + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
  225 +
  226 + }
  227 +
  228 + g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP));
  229 +
  230 + // 1 = Shortcut filename
  231 + {
  232 + gtk_entry_set_text(GTK_ENTRY(inputs[1]),filename);
  233 + gtk_entry_bind_to_filechooser(
  234 + inputs[1],
  235 + GTK_FILE_CHOOSER_ACTION_SAVE,
  236 + _("Save to shortcut file"),
  237 + NULL,
  238 + "*.desktop",
  239 + _("Standard desktop files")
  240 + );
  241 +
  242 + }
  243 +
  244 + // 2 = Session name
  245 + {
  246 + gchar * session_name = g_strdup(v3270_get_session_name(terminal));
  247 + gchar * ptr = strchr(session_name,':');
  248 + if(ptr)
  249 + *ptr = 0;
  250 +
  251 + if(strcmp(session_name,G_STRINGIFY(PRODUCT_NAME)))
  252 + gtk_entry_set_text(GTK_ENTRY(inputs[2]),session_name);
  253 +
  254 + }
  255 +
  256 + // 3 = Session filename
  257 + {
  258 + g_autofree gchar * session_filename = v3270_key_file_build_filename(terminal);
  259 + gtk_entry_set_text(GTK_ENTRY(inputs[3]),session_filename);
  260 +
  261 + gtk_entry_bind_to_filechooser(
  262 + inputs[3],
  263 + GTK_FILE_CHOOSER_ACTION_SAVE,
  264 + _("Save to session filename"),
  265 + NULL,
  266 + "*.3270",
  267 + _("3270 session files")
  268 + );
  269 +
  270 + }
  271 +
  272 + // 4 = Generic name
  273 + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[4]),v3270_get_url(terminal));
  274 + gtk_entry_set_text(GTK_ENTRY(inputs[4]),v3270_get_url(terminal));
  275 + gtk_entry_set_input_hints(GTK_ENTRY(inputs[4]),GTK_INPUT_HINT_SPELLCHECK);
  276 +
  277 + gtk_widget_show_all(GTK_WIDGET(grid));
  278 + return dialog;
  279 + }
  280 +
  281 + static void apply(GtkWidget *dialog, GtkWidget *terminal) {
  282 +
  283 + GError * error = NULL;
  284 + size_t ix;
  285 +
  286 + static const char * key_file_data =
  287 + "[Desktop Entry]\n" \
  288 + "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \
  289 + "Terminal=false\n" \
  290 + "Type=Application\n" \
  291 + "StartupNotify=true\n" \
  292 + "Categories=GTK;GNOME;TerminalEmulator\n" \
  293 + "OnlyShowIn=GNOME;Unity\n";
  294 +
  295 + GKeyFile * keyfile = g_key_file_new();
  296 + g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL);
  297 +
  298 +#ifdef DEBUG
  299 + {
  300 + g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL);
  301 + debug("\n%s\n",dbg_data);
  302 + }
  303 +#endif // DEBUG
  304 +
  305 +
  306 + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
  307 + debug("dialog=%p inputs=%p",dialog,inputs);
  308 +
  309 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  310 + if(entries[ix].key) {
  311 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  312 + g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix])));
  313 + }
  314 + }
  315 +
  316 + // Save keyfile
  317 + v3270_key_file_save_to_file(
  318 + terminal,
  319 + gtk_entry_get_text(GTK_ENTRY(inputs[3])),
  320 + &error
  321 + );
  322 +
  323 + // Get program file name
  324 + // https://stackoverflow.com/questions/4517425/how-to-get-program-path
  325 + if(!error) {
  326 + char buffer[4096];
  327 + g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid());
  328 +
  329 + int bytes = readlink(pidfile,buffer,4095);
  330 +
  331 + if(bytes >= 0)
  332 + buffer[bytes] = '\0';
  333 +
  334 + g_autofree gchar * exec_line =
  335 + g_strconcat(
  336 + buffer,
  337 + " \"",gtk_entry_get_text(GTK_ENTRY(inputs[3])),"\"",
  338 + NULL
  339 + );
  340 +
  341 + g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line);
  342 +
  343 + }
  344 +
  345 + // Save shortcut
  346 + g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[1])),&error);
  347 +
  348 + g_key_file_free(keyfile);
  349 +
  350 + if(error) {
  351 +
  352 + g_message("%s",error->message);
  353 + g_error_free(error);
  354 +
  355 + } else {
  356 +
  357 + // Set session name (after save to avoid changes on the old session file).
  358 + v3270_set_session_name(terminal,gtk_entry_get_text(GTK_ENTRY(inputs[2])));
  359 + v3270_emit_save_settings(terminal,NULL);
  360 +
  361 + }
  362 +
  363 +}
  364 +
  365 +void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
  366 +
  367 + debug("%s(%d)",__FUNCTION__,response_id);
  368 +
  369 + gtk_widget_hide(dialog);
  370 + if(response_id == GTK_RESPONSE_APPLY) {
  371 + apply(dialog,terminal);
  372 + }
  373 +
  374 + gtk_widget_destroy(dialog);
  375 +
  376 +}
  377 +
  378 +
... ...
src/objects/os/windows/savedesktopicon.c 0 → 100644
... ... @@ -0,0 +1,354 @@
  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 + /**
  31 + * @brief Implement Windows version of the save desktop icon action.
  32 + *
  33 + * References:
  34 + *
  35 + * <https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32>
  36 + * <https://docs.microsoft.com/pt-br/windows/win32/shell/links?redirectedfrom=MSDN>
  37 + *
  38 + */
  39 +
  40 +// #include <stdafx.h>
  41 + #include <winsock2.h>
  42 + #include <windows.h>
  43 + #include <winnls.h>
  44 + #include <shobjidl.h>
  45 + #include <objbase.h>
  46 + #include <objidl.h>
  47 + #include <shlguid.h>
  48 +
  49 + #include <v3270.h>
  50 + #include <pw3270.h>
  51 + #include <pw3270/application.h>
  52 + #include <v3270/actions.h>
  53 + #include <lib3270.h>
  54 + #include <lib3270/log.h>
  55 + #include <v3270/tools.h>
  56 + #include <v3270/keyfile.h>
  57 + #include <v3270/settings.h>
  58 +
  59 + static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
  60 + static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
  61 +
  62 + static const struct _entry {
  63 +
  64 + const gchar * label;
  65 + const gchar * tooltip;
  66 + gint margin_top;
  67 + gint width;
  68 +
  69 + } entries[] = {
  70 +
  71 + // 0 - Shorcut file name
  72 + {
  73 + .label = N_("Shortcut file"),
  74 + .tooltip = N_("Path for the new shortcut"),
  75 + .width = 40,
  76 + },
  77 +
  78 + // 1 - Shortcut description
  79 + {
  80 + .label = N_("Description"),
  81 + .width = 20,
  82 + },
  83 +
  84 + // 2 = Session name
  85 + {
  86 + .label = N_("Session name"),
  87 + .margin_top = 12,
  88 + .tooltip = N_("The session name used in the window/tab title (empty for default)"),
  89 + .width = 15,
  90 + },
  91 +
  92 + // 3 = Session file
  93 + {
  94 + .label = N_("Session file"),
  95 + .tooltip = N_("The file with the session preferences for this shortcut"),
  96 + .width = 40,
  97 + }
  98 +
  99 + };
  100 +
  101 + GAction * pw3270_action_save_desktop_icon_new(void) {
  102 +
  103 + V3270SimpleAction * action = v3270_dialog_action_new(factory);
  104 +
  105 + action->name = "save.launcher";
  106 + action->label = _("Save session shortcut");
  107 + action->tooltip = _("Create shortcut for the current session");
  108 +
  109 + return G_ACTION(action);
  110 +
  111 + }
  112 +
  113 + GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
  114 +
  115 + size_t ix;
  116 +
  117 + gboolean use_header;
  118 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  119 +
  120 + GtkWidget * dialog =
  121 + GTK_WIDGET(g_object_new(
  122 + GTK_TYPE_DIALOG,
  123 + "use-header-bar", (use_header ? 1 : 0),
  124 + NULL
  125 + ));
  126 +
  127 + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
  128 + gtk_window_set_title(GTK_WINDOW(dialog),action->label);
  129 +
  130 + gtk_dialog_add_buttons(
  131 + GTK_DIALOG(dialog),
  132 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  133 + _("_Save"), GTK_RESPONSE_APPLY,
  134 + NULL
  135 + );
  136 +
  137 + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
  138 +
  139 + // Create entry fields
  140 + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
  141 + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
  142 + debug("Dialog=%p inputs=%p",dialog,inputs);
  143 +
  144 + GtkGrid * grid = GTK_GRID(gtk_grid_new());
  145 +
  146 + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
  147 +
  148 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  149 + gtk_container_set_border_width(GTK_CONTAINER(grid),18);
  150 + gtk_grid_set_row_spacing(GTK_GRID(grid),6);
  151 + gtk_grid_set_column_spacing(GTK_GRID(grid),12);
  152 +
  153 + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
  154 +
  155 + GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
  156 + gtk_label_set_xalign(GTK_LABEL(label),1);
  157 + gtk_grid_attach(grid,label,0,ix,1,1);
  158 +
  159 + inputs[ix] = gtk_entry_new();
  160 + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
  161 +
  162 + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
  163 + gtk_widget_set_hexpand(inputs[ix],FALSE);
  164 + gtk_widget_set_vexpand(inputs[ix],FALSE);
  165 +
  166 + if(entries[ix].tooltip) {
  167 + gtk_widget_set_tooltip_markup(GTK_WIDGET(inputs[ix]),gettext(entries[ix].tooltip));
  168 + }
  169 +
  170 + if(entries[ix].margin_top) {
  171 + gtk_widget_set_margin_top(label,entries[ix].margin_top);
  172 + gtk_widget_set_margin_top(inputs[ix],entries[ix].margin_top);
  173 + }
  174 +
  175 + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
  176 +
  177 + }
  178 +
  179 + // Setup short-cut name entry.
  180 + {
  181 + gtk_entry_bind_to_filechooser(
  182 + inputs[0],
  183 + GTK_FILE_CHOOSER_ACTION_SAVE,
  184 + _("Save to windows shortcut"),
  185 + NULL,
  186 + "*.lnk",
  187 + _("Windows shortcuts")
  188 + );
  189 +
  190 + gchar * filename = g_strdup_printf(
  191 + "%s\\" G_STRINGIFY(PRODUCT_NAME) ".lnk",
  192 + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)
  193 + );
  194 +
  195 + size_t ix = 0;
  196 +
  197 + while(g_file_test(filename,G_FILE_TEST_EXISTS)) {
  198 +
  199 + g_free(filename);
  200 + filename = g_strdup_printf(
  201 + "%s\\" G_STRINGIFY(PRODUCT_NAME) "%u.lnk",
  202 + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP),
  203 + (unsigned int) ++ix
  204 + );
  205 +
  206 + }
  207 +
  208 + gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);
  209 + g_free(filename);
  210 + }
  211 +
  212 + {
  213 + g_autofree gchar * session_filename = v3270_key_file_build_filename(terminal);
  214 + gtk_entry_set_text(GTK_ENTRY(inputs[3]),session_filename);
  215 +
  216 + gtk_entry_bind_to_filechooser(
  217 + inputs[3],
  218 + GTK_FILE_CHOOSER_ACTION_SAVE,
  219 + _("File for session preferences"),
  220 + NULL,
  221 + "*.3270",
  222 + _("3270 session files")
  223 + );
  224 +
  225 + }
  226 +
  227 + gtk_widget_show_all(GTK_WIDGET(grid));
  228 + return dialog;
  229 + }
  230 +
  231 + static HRESULT CreateShortCut(const char * pszTargetfile, const char * pszTargetargs, const char * pszLinkfile, const char * pszDescription, int iShowmode, const char * pszCurdir, LPSTR pszIconfile, int iIconindex) {
  232 +
  233 + // https://www.codeproject.com/Articles/11467/How-to-create-short-cuts-link-files
  234 + IShellLink* pShellLink; // IShellLink object pointer
  235 + IPersistFile* pPersistFile; // IPersistFile object pointer
  236 + WORD wszLinkfile[MAX_PATH]; // pszLinkfile as Unicode string
  237 + int iWideCharsWritten; // Number of wide characters written
  238 +
  239 + HRESULT hRes =
  240 + CoCreateInstance(
  241 + &CLSID_ShellLink, // predefined CLSID of the IShellLink object
  242 + NULL, // pointer to parent interface if part of aggregate
  243 + CLSCTX_INPROC_SERVER, // caller and called code are in same process
  244 + &IID_IShellLink, // predefined interface of the IShellLink object
  245 + (void **) &pShellLink); // Returns a pointer to the IShellLink object
  246 +
  247 + if(!SUCCEEDED(hRes)) {
  248 + return hRes;
  249 + }
  250 +
  251 + if(pszTargetfile && strlen(pszTargetfile)) {
  252 + hRes = pShellLink->lpVtbl->SetPath(pShellLink,pszTargetfile);
  253 + } else {
  254 + char filename[MAX_PATH+1];
  255 + memset(filename,0,MAX_PATH+1);
  256 + GetModuleFileName(NULL,filename,MAX_PATH);
  257 + hRes = pShellLink->lpVtbl->SetPath(pShellLink,filename);
  258 + }
  259 +
  260 + if(pszTargetargs) {
  261 + hRes = pShellLink->lpVtbl->SetArguments(pShellLink,pszTargetargs);
  262 + } else {
  263 + hRes = pShellLink->lpVtbl->SetArguments(pShellLink,"");
  264 + }
  265 +
  266 + if(pszDescription && strlen(pszDescription) > 0) {
  267 + hRes = pShellLink->lpVtbl->SetDescription(pShellLink,pszDescription);
  268 + } else {
  269 + hRes = pShellLink->lpVtbl->SetDescription(pShellLink,_("IBM 3270 Terminal emulator"));
  270 + }
  271 +
  272 + if(iShowmode > 0) {
  273 + hRes = pShellLink->lpVtbl->SetShowCmd(pShellLink,iShowmode);
  274 + }
  275 +
  276 + if(pszCurdir && strlen(pszCurdir) > 0) {
  277 + hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,pszCurdir);
  278 + } else {
  279 + g_autofree gchar * appdir = g_win32_get_package_installation_directory_of_module(NULL);
  280 + hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,appdir);
  281 + }
  282 +
  283 + if(pszIconfile && strlen(pszIconfile) > 0 && iIconindex >= 0) {
  284 + hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, pszIconfile, iIconindex);
  285 + }
  286 +
  287 + // Use the IPersistFile object to save the shell link
  288 + hRes = pShellLink->lpVtbl->QueryInterface(
  289 + pShellLink, // existing IShellLink object
  290 + &IID_IPersistFile, // pre-defined interface of the IPersistFile object
  291 + (void **) &pPersistFile); // returns a pointer to the IPersistFile object
  292 +
  293 +
  294 + if(SUCCEEDED(hRes)){
  295 + iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, pszLinkfile, -1, wszLinkfile, MAX_PATH);
  296 + hRes = pPersistFile->lpVtbl->Save(pPersistFile,wszLinkfile, TRUE);
  297 + pPersistFile->lpVtbl->Release(pPersistFile);
  298 + }
  299 +
  300 + pShellLink->lpVtbl->Release(pShellLink);
  301 +
  302 + return hRes;
  303 + }
  304 +
  305 + void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
  306 +
  307 + debug("%s(%d)",__FUNCTION__,response_id);
  308 +
  309 + if(response_id == GTK_RESPONSE_APPLY) {
  310 +
  311 + // Save desktop icon
  312 + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs");
  313 +
  314 + // Save keyfile
  315 + GError * error = NULL;
  316 + v3270_key_file_save_to_file(
  317 + terminal,
  318 + gtk_entry_get_text(GTK_ENTRY(inputs[3])),
  319 + &error
  320 + );
  321 +
  322 + if(!error) {
  323 +
  324 + HRESULT hRes = CreateShortCut(
  325 + NULL, // LPSTR pszTargetfile,
  326 + gtk_entry_get_text(GTK_ENTRY(inputs[3])), // LPSTR pszTargetargs,
  327 + gtk_entry_get_text(GTK_ENTRY(inputs[0])), // LPSTR pszLinkfile,
  328 + gtk_entry_get_text(GTK_ENTRY(inputs[1])), // LPSTR pszDescription,
  329 + 0,
  330 + NULL,
  331 + NULL,
  332 + 0
  333 + );
  334 +
  335 + }
  336 +
  337 + if(error) {
  338 +
  339 + g_message("%s",error->message);
  340 + g_error_free(error);
  341 +
  342 + } else {
  343 +
  344 + // Set session name (after save to avoid changes on the old session file).
  345 + v3270_set_session_name(terminal,gtk_entry_get_text(GTK_ENTRY(inputs[2])));
  346 + v3270_emit_save_settings(terminal,NULL);
  347 +
  348 + }
  349 +
  350 + }
  351 +
  352 + gtk_widget_destroy(dialog);
  353 +
  354 +}
... ...
src/objects/settings/actionview.c 0 → 100644
... ... @@ -0,0 +1,207 @@
  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 +#ifdef _WIN32
  31 + #include <winsock2.h>
  32 + #include <windows.h>
  33 +#endif // _WIN32
  34 +
  35 + #include <pw3270.h>
  36 + #include <pw3270/settings.h>
  37 + #include <lib3270.h>
  38 + #include <lib3270/log.h>
  39 + #include <pw3270/actions.h>
  40 +
  41 + struct _PW3270SettingsActions {
  42 + GtkGrid parent;
  43 + GtkWidget * views[3];
  44 + GtkTreeModel * model;
  45 + };
  46 +
  47 + struct _PW3270SettingsActionsClass {
  48 + GtkGridClass parent;
  49 +
  50 + int dunno;
  51 + };
  52 +
  53 + G_DEFINE_TYPE(PW3270SettingsActions, PW3270SettingsActions, GTK_TYPE_GRID);
  54 +
  55 + static void PW3270SettingsActions_class_init(PW3270SettingsActionsClass *klass) {
  56 +
  57 + }
  58 +
  59 + static void PW3270SettingsActions_init(PW3270SettingsActions *grid) {
  60 +
  61 + size_t ix;
  62 +
  63 + static const struct View {
  64 + const gchar *label;
  65 + const gchar *tooltip;
  66 + } views[G_N_ELEMENTS(grid->views)] = {
  67 + {
  68 + .label = N_("Start"),
  69 + .tooltip = N_("Items packed from the start to the end")
  70 + },
  71 +
  72 + {
  73 + .label = N_("Available"),
  74 + .tooltip = N_("List of the available and unpacked actions")
  75 + },
  76 +
  77 + {
  78 + .label = N_("End"),
  79 + .tooltip = N_("Items packed from the end to the start")
  80 + }
  81 + };
  82 +
  83 + gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
  84 + gtk_grid_set_row_spacing(GTK_GRID(grid),12);
  85 + gtk_grid_set_column_spacing(GTK_GRID(grid),6);
  86 +
  87 + {
  88 + // Create views
  89 + GtkTreeSelection * selection;
  90 + GtkWidget *box;
  91 +
  92 + for(ix = 0; ix < G_N_ELEMENTS(grid->views); ix++) {
  93 +
  94 + // Create label.
  95 + GtkWidget * label = gtk_label_new(gettext(views[ix].label));
  96 + gtk_widget_set_tooltip_markup(label,gettext(views[ix].tooltip));
  97 + gtk_label_set_xalign(GTK_LABEL(label),0);
  98 + gtk_widget_set_hexpand(label,TRUE);
  99 + gtk_widget_set_vexpand(label,FALSE);
  100 +
  101 + gtk_grid_attach(
  102 + GTK_GRID(grid),
  103 + label,
  104 + (ix*2),0,
  105 + 1,1
  106 + );
  107 +
  108 + // Create view
  109 + grid->views[ix] = pw3270_action_view_new();
  110 + gtk_widget_set_hexpand(grid->views[ix],TRUE);
  111 + gtk_widget_set_vexpand(grid->views[ix],TRUE);
  112 +
  113 + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(grid->views[ix]));
  114 + gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
  115 +
  116 + GtkWidget * box = gtk_scrolled_window_new(NULL,NULL);
  117 + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(box),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
  118 + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(box),GTK_SHADOW_ETCHED_IN);
  119 + gtk_container_add(GTK_CONTAINER(box),grid->views[ix]);
  120 +
  121 + gtk_grid_attach(
  122 + GTK_GRID(grid),
  123 + box,
  124 + (ix*2),1,
  125 + 1,5
  126 + );
  127 +
  128 + }
  129 +
  130 + }
  131 +
  132 + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(grid->views[0]),TRUE);
  133 + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(grid->views[2]),TRUE);
  134 + pw3270_action_view_order_by_label(grid->views[1]);
  135 +
  136 + // Create buttons
  137 + {
  138 + GtkWidget *buttons[] = {
  139 + pw3270_action_view_move_button_new(grid->views[1],grid->views[0],"go-previous"),
  140 + pw3270_action_view_move_button_new(grid->views[1],grid->views[2],"go-next"),
  141 + pw3270_action_view_move_button_new(grid->views[0],grid->views[1],"go-next"),
  142 + pw3270_action_view_move_button_new(grid->views[2],grid->views[1],"go-previous")
  143 + };
  144 +
  145 + gtk_grid_attach(GTK_GRID(grid),buttons[0],1,2,1,1);
  146 + gtk_grid_attach(GTK_GRID(grid),buttons[1],3,2,1,1);
  147 +
  148 + gtk_grid_attach(GTK_GRID(grid),buttons[2],1,3,1,1);
  149 + gtk_grid_attach(GTK_GRID(grid),buttons[3],3,3,1,1);
  150 +
  151 + }
  152 +
  153 + }
  154 +
  155 + GtkWidget * pw3270_settings_actions_new() {
  156 +
  157 + return GTK_WIDGET(g_object_new(
  158 + GTK_TYPE_PW3270_SETTINGS_ACTIONS,
  159 + NULL
  160 + ));
  161 +
  162 + }
  163 +
  164 + Pw3270ActionList * pw3270_settings_action_set(GtkWidget *widget, Pw3270ActionList *action_list, const gchar *action_names) {
  165 +
  166 + PW3270SettingsActions *editor = (PW3270SettingsActions *) widget;
  167 +
  168 + static const unsigned short columns[] = { 0, 2 };
  169 + unsigned short column;
  170 + size_t action;
  171 +
  172 + gchar **views = g_strsplit(action_names,":",-1);
  173 +
  174 + for(column = 0; column < G_N_ELEMENTS(columns); column++) {
  175 +
  176 + if(!views[column])
  177 + break;
  178 +
  179 + gchar ** actions = g_strsplit(views[column],",",-1);
  180 +
  181 + for(action = 0; actions[action];action++) {
  182 + action_list = pw3270_action_list_move_action(
  183 + action_list,
  184 + actions[action],
  185 + editor->views[columns[column]]
  186 + );
  187 + }
  188 +
  189 + g_strfreev(actions);
  190 + }
  191 +
  192 + g_strfreev(views);
  193 +
  194 + pw3270_action_view_set_actions(editor->views[1], action_list);
  195 +
  196 + return action_list;
  197 + }
  198 +
  199 + gchar * pw3270_settings_action_get(GtkWidget *widget) {
  200 +
  201 + PW3270SettingsActions *editor = (PW3270SettingsActions *) widget;
  202 +
  203 + g_autofree gchar * left_names = pw3270_action_view_get_action_names(editor->views[0]);
  204 + g_autofree gchar * right_names = pw3270_action_view_get_action_names(editor->views[2]);
  205 + return g_strconcat(left_names,":",right_names,NULL);
  206 +
  207 + }
... ...
src/objects/settings/dialog.c
... ... @@ -71,11 +71,6 @@ static void PW3270SettingsDialog_init(PW3270SettingsDialog *dialog)
71 71 // Get use of header bar.
72 72 g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &dialog->has_subtitle, NULL);
73 73  
74   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
75   - //gtk_box_set_spacing(GTK_BOX(content_area),18);
76   - //gtk_container_set_border_width(GTK_CONTAINER(content_area),18);
77   -
78   -// gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE);
79 74 gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
80 75  
81 76 gtk_dialog_add_buttons(
... ... @@ -102,7 +97,7 @@ static void PW3270SettingsDialog_init(PW3270SettingsDialog *dialog)
102 97  
103 98 }
104 99  
105   -GtkWidget * pw3270_settings_dialog_new(GAction *action) {
  100 +GtkWidget * pw3270_settings_dialog_new(GAction *action, gboolean has_subtitle) {
106 101  
107 102 #ifdef _WIN32
108 103  
... ... @@ -115,7 +110,7 @@ GtkWidget * pw3270_settings_dialog_new(GAction *action) {
115 110  
116 111 #elif GTK_CHECK_VERSION(3,12,0)
117 112  
118   - gboolean use_header;
  113 + gboolean use_header = FALSE;
119 114 g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
120 115  
121 116 GtkWidget * dialog =
... ... @@ -131,6 +126,8 @@ GtkWidget * pw3270_settings_dialog_new(GAction *action) {
131 126  
132 127 #endif // GTK 3.12
133 128  
  129 + GTK_PW3270_SETTINGS_DIALOG(dialog)->has_subtitle = has_subtitle;
  130 +
134 131 if(action) {
135 132  
136 133 if(PW3270_IS_ACTION(action)) {
... ... @@ -202,6 +199,7 @@ void add(GtkContainer *container, GtkWidget *widget) {
202 199 settings->load(widget,settings->settings);
203 200 }
204 201  
  202 + gtk_widget_show(widget);
205 203 gtk_notebook_append_page(
206 204 GTK_PW3270_SETTINGS_DIALOG(container)->tabs,
207 205 widget,
... ... @@ -216,20 +214,11 @@ void page_changed(GtkNotebook *notebook, GtkWidget G_GNUC_UNUSED(*child), guint
216 214  
217 215 void switch_page(GtkNotebook *notebook, PW3270Settings *page, guint G_GNUC_UNUSED(page_num), PW3270SettingsDialog *dialog) {
218 216  
219   - if(gtk_notebook_get_n_pages(notebook) > 1) {
220   -
221   - GtkWidget * header_bar = gtk_dialog_get_header_bar(GTK_DIALOG(dialog));
222   -
223   - if(header_bar) {
224   - gtk_header_bar_set_subtitle(GTK_HEADER_BAR(header_bar),page->title);
225   - }
226   -
227   - } else if(page->title) {
228   -
229   - gtk_window_set_title(GTK_WINDOW(dialog),page->title);
  217 + GtkWidget * header_bar = gtk_dialog_get_header_bar(GTK_DIALOG(dialog));
230 218  
  219 + if(header_bar && dialog->has_subtitle) {
  220 + gtk_header_bar_set_subtitle(GTK_HEADER_BAR(header_bar),page->title);
231 221 }
232 222  
233   -
234 223 }
235 224  
... ...
src/objects/toolbar/actions.c
... ... @@ -65,21 +65,35 @@
65 65  
66 66 if(!action) {
67 67 const gchar *ptr = strchr(name,'.');
68   -
69 68 if(ptr) {
70 69 action = g_action_map_lookup_action(G_ACTION_MAP(window), ptr+1);
71   - debug("action(%s)=%p",ptr+1,action);
72 70 }
  71 + }
73 72  
  73 + if(!action) {
  74 + action = g_action_map_lookup_action(G_ACTION_MAP(g_application_get_default()),name);
  75 + }
  76 +
  77 + if(!action) {
  78 + const gchar *ptr = strchr(name,'.');
  79 + if(ptr) {
  80 + action = g_action_map_lookup_action(G_ACTION_MAP(g_application_get_default()), ptr+1);
  81 + }
74 82 }
75 83  
76 84 debug("%s(%s)=%p",__FUNCTION__,name,action);
77 85  
78   - if(action) {
79   - debug("Creating button \"%s\" from action \"%s\"",name,g_action_get_name(G_ACTION(action)));
80   - item = gtk_tool_button_new_from_action(action,GTK_ICON_SIZE_LARGE_TOOLBAR);
  86 + if(!action) {
  87 + g_warning("Can't find action \"%s\"",name);
  88 + return NULL;
81 89 }
82 90  
  91 + item = gtk_tool_button_new_from_action(
  92 + action,
  93 + GTK_ICON_SIZE_LARGE_TOOLBAR,
  94 + pw3270_toolbar_get_icon_type(GTK_TOOLBAR(toolbar)) == 1
  95 + );
  96 +
83 97 if(item) {
84 98  
85 99 gtk_widget_show_all(GTK_WIDGET(item));
... ...
src/objects/toolbar/models.c 0 → 100644
... ... @@ -0,0 +1,277 @@
  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 "private.h"
  31 + #include <pw3270/application.h>
  32 + #include <pw3270/settings.h>
  33 + #include <pw3270/window.h>
  34 +
  35 + #define GTK_TOOLBAR_DEFAULT_STYLE ((GtkToolbarStyle) -1)
  36 +
  37 + struct _contents {
  38 + const gchar * label;
  39 + int value;
  40 + };
  41 +
  42 + static const struct _models {
  43 + const gchar *name;
  44 + const gchar *property;
  45 + const gchar *label;
  46 + const struct _contents *contents;
  47 + } models[] = {
  48 +
  49 + {
  50 + "toolbar-icon-size",
  51 + "icon-size",
  52 + N_("Icon _size"),
  53 + (const struct _contents[]) {
  54 + {
  55 + .label = N_( "System default" ),
  56 + .value = GTK_ICON_SIZE_INVALID
  57 +
  58 + },
  59 +
  60 + {
  61 + .label = N_( "Small" ),
  62 + .value = GTK_ICON_SIZE_SMALL_TOOLBAR
  63 + },
  64 +
  65 + {
  66 + .label = N_( "Large" ),
  67 + .value = GTK_ICON_SIZE_LARGE_TOOLBAR
  68 + },
  69 +
  70 + {
  71 + .label = NULL
  72 + }
  73 + }
  74 + },
  75 +
  76 + {
  77 + "toolbar-style",
  78 + "style",
  79 + N_("Toolbar s_tyle"),
  80 + (const struct _contents[]) {
  81 + {
  82 + .label = N_( "System default" ),
  83 + .value = GTK_TOOLBAR_DEFAULT_STYLE
  84 + },
  85 +
  86 + {
  87 + .label = N_( "Icons only" ),
  88 + .value = GTK_TOOLBAR_ICONS
  89 + },
  90 +
  91 + {
  92 + .label = N_( "Text only" ),
  93 + .value = GTK_TOOLBAR_TEXT
  94 + },
  95 +
  96 + {
  97 + .label = N_( "Icons & text" ),
  98 + .value = GTK_TOOLBAR_BOTH
  99 + },
  100 + {
  101 + .label = NULL
  102 + }
  103 + }
  104 + },
  105 + {
  106 + "toolbar-icon-type",
  107 + "icon-type",
  108 + N_("Icon type"),
  109 + (const struct _contents[]) {
  110 + {
  111 + .label = N_( "System default" ),
  112 + .value = 0
  113 + },
  114 + {
  115 + .label = N_( "Symbolic" ),
  116 + .value = 1
  117 + },
  118 + {
  119 + .label = NULL
  120 + }
  121 + }
  122 + }
  123 +
  124 + };
  125 +
  126 + GtkTreeModel * pw3270_model_from_name(const gchar *name) {
  127 +
  128 + size_t model;
  129 +
  130 + for(model = 0; model < G_N_ELEMENTS(models); model++) {
  131 +
  132 + if(g_ascii_strcasecmp(models[model].name,name))
  133 + continue;
  134 +
  135 + // Create model
  136 + size_t row;
  137 + GtkTreeIter iter;
  138 + GtkListStore * store = gtk_list_store_new(2, G_TYPE_STRING,G_TYPE_UINT);
  139 +
  140 + for(row = 0; models[model].contents[row].label; row++) {
  141 + gtk_list_store_append(store,&iter);
  142 + gtk_list_store_set( store,
  143 + &iter,
  144 + 0, gettext(models[model].contents[row].label),
  145 + 1, models[model].contents[row].value,
  146 + -1);
  147 + }
  148 +
  149 + return GTK_TREE_MODEL(store);
  150 +
  151 + }
  152 +
  153 + g_warning("Can't create combobox '%s'",name);
  154 + return NULL;
  155 + }
  156 +
  157 + void pw3270_model_get_iter_from_value(GtkTreeModel * model, GtkTreeIter *iter, guint value) {
  158 +
  159 + if(gtk_tree_model_get_iter_first(model,iter)) {
  160 +
  161 + do {
  162 +
  163 + GValue gVal = { 0, };
  164 + gtk_tree_model_get_value(model,iter,1,&gVal);
  165 + guint iVal = g_value_get_uint(&gVal);
  166 + g_value_unset(&gVal);
  167 +
  168 + if(iVal == value) {
  169 + return;
  170 + }
  171 +
  172 + } while(gtk_tree_model_iter_next(model,iter));
  173 +
  174 + }
  175 +
  176 + }
  177 +
  178 + guint pw3270_model_get_value_from_iter(GtkTreeModel * model, GtkTreeIter *iter) {
  179 + GValue gVal = { 0, };
  180 + gtk_tree_model_get_value(model,iter,1,&gVal);
  181 + guint iVal = g_value_get_uint(&gVal);
  182 + g_value_unset(&gVal);
  183 + return iVal;
  184 + }
  185 +
  186 + static void set_property(GObject *menuitem, GObject *widget) {
  187 +
  188 + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) {
  189 +
  190 + const struct _contents *model = (const struct _contents *) g_object_get_data(menuitem, I_("pw3270_model_data"));
  191 + const char *name = (const char *) g_object_get_data(menuitem, I_("pw3270_property_name"));
  192 +
  193 + debug("%s(%s,%d)",__FUNCTION__,name,model->value);
  194 + g_object_set(widget,name,model->value,NULL);
  195 +
  196 + }
  197 +
  198 + }
  199 +
  200 + static void set_toggle_menu_item(GtkCheckMenuItem *item, gint *value) {
  201 + const struct _contents *model = (const struct _contents *) g_object_get_data(G_OBJECT(item), I_("pw3270_model_data"));
  202 + if(model) {
  203 + gtk_check_menu_item_set_active(item,model->value == *value);
  204 + }
  205 + }
  206 +
  207 + static void property_changed(GObject *widget, GParamSpec G_GNUC_UNUSED(*pspec), GtkContainer *menu) {
  208 +
  209 + gint value = -1;
  210 + const gchar * name = g_object_get_data(G_OBJECT(menu), I_("pw3270_property_name"));
  211 + g_object_get(widget,name,&value,NULL);
  212 +
  213 + debug("%s(%p,%s)=%d",__FUNCTION__,widget,name,value);
  214 +
  215 + gtk_container_foreach(menu,(GtkCallback) set_toggle_menu_item,&value);
  216 +
  217 +
  218 + }
  219 +
  220 + GtkWidget * pw3270_menu_item_from_model(GtkWidget *widget, const gchar *name) {
  221 +
  222 + size_t model;
  223 +
  224 +
  225 + for(model = 0; model < G_N_ELEMENTS(models); model++) {
  226 +
  227 + if(g_ascii_strcasecmp(models[model].name,name))
  228 + continue;
  229 +
  230 + // Create submenu
  231 + size_t row;
  232 + GtkWidget * item;
  233 + GtkWidget * menu = gtk_menu_item_new_with_mnemonic(gettext(models[model].label));
  234 +
  235 + GtkWidget * submenu = gtk_menu_new();
  236 + g_object_set_data(G_OBJECT(submenu),I_("pw3270_property_name"),(gpointer) models[model].property);
  237 + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu),submenu);
  238 +
  239 + gint selected = -1;
  240 + if(widget) {
  241 + g_object_get(G_OBJECT(widget),models[model].property,&selected,NULL);
  242 + g_autofree gchar * signame = g_strconcat("notify::",models[model].property,NULL);
  243 + g_signal_connect(G_OBJECT(widget),signame,G_CALLBACK(property_changed),submenu);
  244 + }
  245 +
  246 + for(row = 0; models[model].contents[row].label; row++) {
  247 +
  248 + item = gtk_check_menu_item_new_with_mnemonic(gettext(models[model].contents[row].label));
  249 + gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item),TRUE);
  250 +
  251 + g_object_set_data(G_OBJECT(item),I_("pw3270_property_name"),(gpointer) models[model].property);
  252 + g_object_set_data(G_OBJECT(item),I_("pw3270_model_data"),(gpointer) &models[model].contents[row]);
  253 +
  254 + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),selected == models[model].contents[row].value);
  255 +
  256 + if(widget) {
  257 + g_signal_connect(item, "toggled", G_CALLBACK(set_property), widget);
  258 + }
  259 +
  260 + gtk_menu_shell_append(GTK_MENU_SHELL(submenu),item);
  261 +
  262 + }
  263 +
  264 + gtk_widget_show_all(menu);
  265 +
  266 + return menu;
  267 + }
  268 +
  269 + return NULL;
  270 + }
  271 +
  272 + void pw3270_menu_item_set_value(GtkWidget *menu, guint value) {
  273 +
  274 + debug("%s(%p,%d)",__FUNCTION__,menu,value);
  275 +
  276 + }
  277 +
... ...
src/objects/toolbar/private.h
... ... @@ -37,6 +37,9 @@
37 37 #define GETTEXT_PACKAGE PACKAGE_NAME
38 38 #endif
39 39  
  40 + /* not really I18N-related, but also a string marker macro */
  41 + #define I_(string) g_intern_static_string (string)
  42 +
40 43 #include <libintl.h>
41 44 #include <glib/gi18n.h>
42 45 #include <gtk/gtk.h>
... ... @@ -47,8 +50,9 @@
47 50 G_GNUC_INTERNAL GtkWidget * pw3270_tool_button_new(GAction *action);
48 51 G_GNUC_INTERNAL GtkWidget * pw3270_tool_button_new_from_action_name(const gchar * action_name);
49 52  
50   - G_GNUC_INTERNAL GtkTreeModel * pw3270_toolbar_style_model_new();
51   - G_GNUC_INTERNAL GtkTreeModel * pw3270_toolbar_icon_size_model_new();
  53 + GtkTreeModel * pw3270_model_from_name(const gchar *name);
  54 + GtkWidget * pw3270_menu_item_from_model(GtkWidget *widget, const gchar *model_name);
  55 + void pw3270_menu_item_set_value(GtkWidget *menu, guint value);
52 56  
53 57 G_GNUC_INTERNAL void pw3270_model_get_iter_from_value(GtkTreeModel * model, GtkTreeIter *iter, guint value);
54 58 G_GNUC_INTERNAL guint pw3270_model_get_value_from_iter(GtkTreeModel * model, GtkTreeIter *iter);
... ...
src/objects/toolbar/settings.c
... ... @@ -41,45 +41,43 @@
41 41 /*--[ Constants ]------------------------------------------------------------------------------------*/
42 42  
43 43 static const struct _comboboxes {
44   - const gchar * name;
45   - const gchar * label;
  44 + const gchar * name; ///< @brief The gsettings name.
  45 + const gchar * label; ///< @brief The combo name.
  46 + guint left;
  47 + guint top;
46 48 } comboboxes[] = {
47 49  
48 50 {
  51 + .left = 0,
  52 + .top = 0,
49 53 .name = "toolbar-icon-size",
50 54 .label = N_("Icon Size"),
51 55 },
52 56  
53 57 {
  58 + .left = 3,
  59 + .top = 0,
  60 + .name = "toolbar-icon-type",
  61 + .label = N_("Icon Style")
  62 + },
  63 +
  64 + {
  65 + .left = 0,
  66 + .top = 1,
54 67 .name = "toolbar-style",
55   - .label = N_("Style")
  68 + .label = N_("Toolbar Style")
56 69 }
57 70  
58 71 };
59 72  
60 73 struct _PW3270SettingsPrivate {
61 74 GtkWidget * views[2];
62   - GtkWidget * buttons[2];
63   - GtkTreeModel * models[2];
  75 +// GtkTreeModel * models[G_N_ELEMENTS(comboboxes)];
64 76 GtkWidget * combos[G_N_ELEMENTS(comboboxes)];
65 77 };
66 78  
67 79 /*--[ Implement ]------------------------------------------------------------------------------------*/
68 80  
69   - static void selection_changed(GtkTreeSelection *selection, GtkWidget *button) {
70   - gtk_widget_set_sensitive(button,gtk_tree_selection_count_selected_rows(selection) > 0);
71   - }
72   -
73   - void toolbar_insert(GtkButton G_GNUC_UNUSED(*button), PW3270SettingsPrivate *settings) {
74   - debug("%s(%p)",__FUNCTION__,settings);
75   - pw3270_action_view_move_selected(settings->views[1],settings->views[0]);
76   - }
77   -
78   - void toolbar_remove(GtkButton G_GNUC_UNUSED(*button), PW3270SettingsPrivate *settings) {
79   - debug("%s(%p)",__FUNCTION__,settings);
80   - pw3270_action_view_move_selected(settings->views[0],settings->views[1]);
81   - }
82   -
83 81 GtkWidget * pw3270_toolbar_settings_new() {
84 82  
85 83 size_t ix;
... ... @@ -132,6 +130,7 @@
132 130  
133 131 GtkWidget * box = gtk_scrolled_window_new(NULL,NULL);
134 132 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(box),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
  133 + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(box),GTK_SHADOW_ETCHED_IN);
135 134 gtk_container_add(GTK_CONTAINER(box),page->views[ix]);
136 135  
137 136 gtk_grid_attach(
... ... @@ -143,50 +142,20 @@
143 142 }
144 143  
145 144 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(page->views[0]),TRUE);
146   - gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(page->views[1]))), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
  145 + pw3270_action_view_order_by_label(page->views[1]);
147 146  
148 147 // Create buttons
149   - static const gchar * icon_names[G_N_ELEMENTS(page->buttons)] = {
150   - "go-next",
151   - "go-previous"
152   - };
153   -
154 148 GtkWidget * box = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
155 149 gtk_widget_set_hexpand(box,FALSE);
156 150 gtk_widget_set_vexpand(box,FALSE);
157 151  
158   - for(ix = 0; ix < G_N_ELEMENTS(icon_names); ix++) {
159   - page->buttons[ix] = gtk_button_new_from_icon_name(icon_names[ix],GTK_ICON_SIZE_DND);
160   -
161   - gtk_widget_set_focus_on_click(page->buttons[ix],FALSE);
162   - gtk_button_set_relief(GTK_BUTTON(page->buttons[ix]),GTK_RELIEF_NONE);
163   - gtk_widget_set_sensitive(page->buttons[ix],FALSE);
164   -
165   - g_signal_connect(
166   - gtk_tree_view_get_selection(GTK_TREE_VIEW(page->views[ix])),
167   - "changed",
168   - G_CALLBACK(selection_changed),
169   - page->buttons[ix]
170   - );
171   -
172   - }
173   -
174   - gtk_box_pack_start(GTK_BOX(box),page->buttons[0],FALSE,FALSE,0);
175   - gtk_box_pack_end(GTK_BOX(box),page->buttons[1],FALSE,FALSE,0);
176   -
177   - g_signal_connect(
178   - page->buttons[0],
179   - "clicked",
180   - G_CALLBACK(toolbar_remove),
181   - page
182   - );
  152 + GtkWidget * buttons[] = {
  153 + pw3270_action_view_move_button_new(page->views[0],page->views[1],"go-next"),
  154 + pw3270_action_view_move_button_new(page->views[1],page->views[0],"go-previous"),
  155 + };
183 156  
184   - g_signal_connect(
185   - page->buttons[1],
186   - "clicked",
187   - G_CALLBACK(toolbar_insert),
188   - page
189   - );
  157 + gtk_box_pack_start(GTK_BOX(box),buttons[0],FALSE,FALSE,0);
  158 + gtk_box_pack_end(GTK_BOX(box),buttons[1],FALSE,FALSE,0);
190 159  
191 160 gtk_grid_attach(
192 161 grid,
... ... @@ -197,7 +166,7 @@
197 166 }
198 167  
199 168 //
200   - // Create style & icon size settings.
  169 + // Create Combos.
201 170 //
202 171 {
203 172 GtkGrid * grid = GTK_GRID(gtk_grid_new());
... ... @@ -213,25 +182,24 @@
213 182 gtk_grid_set_column_spacing(grid,12);
214 183 gtk_widget_set_hexpand(GTK_WIDGET(grid),TRUE);
215 184  
216   - page->models[0] = pw3270_toolbar_icon_size_model_new();
217   - page->models[1] = pw3270_toolbar_style_model_new();
218   -
219 185 GtkCellRenderer * renderer = gtk_cell_renderer_text_new();
220 186  
221   - for(ix = 0; ix < G_N_ELEMENTS(page->models); ix++) {
  187 + for(ix = 0; ix < G_N_ELEMENTS(page->combos); ix++) {
  188 +
  189 + GtkTreeModel *model = pw3270_model_from_name(comboboxes[ix].name);
222 190  
223 191 GtkWidget * label = gtk_label_new(gettext(comboboxes[ix].label));
224 192 gtk_label_set_xalign(GTK_LABEL(label),1);
225 193  
226   - gtk_grid_attach(grid,label,(ix*3),0,1,1);
  194 + gtk_grid_attach(grid,label,comboboxes[ix].left,comboboxes[ix].top,1,1);
227 195  
228   - page->combos[ix] = gtk_combo_box_new_with_model(page->models[ix]);
229   - gtk_widget_set_hexpand(page->combos[ix],TRUE);
  196 + page->combos[ix] = gtk_combo_box_new_with_model(model);
  197 + gtk_widget_set_hexpand(page->combos[ix],FALSE);
230 198  
231 199 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(page->combos[ix]), renderer, TRUE);
232 200 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(page->combos[ix]), renderer, "text", 0, NULL);
233 201  
234   - gtk_grid_attach(grid,page->combos[ix],(ix*3)+1,0,2,1);
  202 + gtk_grid_attach(grid,page->combos[ix],comboboxes[ix].left+1,comboboxes[ix].top,2,1);
235 203  
236 204 }
237 205  
... ... @@ -273,12 +241,11 @@
273 241  
274 242 // Load available actions.
275 243 pw3270_action_view_set_actions(page->views[1], action_list);
276   - pw3270_action_view_append(page->views[1], _( "Separator"), NULL, "separator", 1);
  244 + pw3270_action_view_append(page->views[1], _( "Separator"), NULL, "separator", PW3270_ACTION_VIEW_FLAG_ALLOW_ADD);
277 245  
278 246 pw3270_action_list_free(action_list);
279 247  
280 248 GtkTreeIter iter;
281   -
282 249 for(ix = 0; ix < G_N_ELEMENTS(page->combos); ix++) {
283 250  
284 251 pw3270_model_get_iter_from_value(
... ... @@ -298,13 +265,9 @@
298 265 size_t ix;
299 266 g_autoptr(GSettings) settings = pw3270_application_window_settings_new();
300 267  
301   - debug("%s",__FUNCTION__);
302   -
303 268 g_autofree gchar * action_names = pw3270_action_view_get_action_names(page->views[0]);
304 269 g_settings_set_string(settings,"toolbar-action-names",action_names);
305 270  
306   - debug("[%s]",action_names);
307   -
308 271 GtkTreeIter iter;
309 272 for(ix = 0; ix < G_N_ELEMENTS(page->combos); ix++) {
310 273  
... ... @@ -322,48 +285,3 @@
322 285  
323 286 }
324 287  
325   - /*
326   -
327   - typedef struct _ToolbarSettingsPage {
328   - Pw3270SettingsPage parent;
329   - GtkWidget * views[2];
330   - GtkWidget * buttons[2];
331   - GtkTreeModel * models[2];
332   - GtkWidget * combos[G_N_ELEMENTS(comboboxes)];
333   -
334   - } ToolbarSettingsPage;
335   -
336   - static void load(Pw3270SettingsPage *pg, GtkApplication *application) {
337   -
338   - size_t ix;
339   - ToolbarSettingsPage * page = (ToolbarSettingsPage *) pg;
340   - g_autoptr(GSettings) settings = pw3270_application_window_settings_new();
341   -
342   - debug("%s",__FUNCTION__);
343   -
344   -
345   - }
346   -
347   - static void apply(Pw3270SettingsPage *pg, GtkApplication G_GNUC_UNUSED(*application)) {
348   -
349   - }
350   -
351   -
352   - Pw3270SettingsPage * pw3270_toolbar_settings_new() {
353   -
354   - size_t ix;
355   -
356   - ToolbarSettingsPage * page = g_new0(ToolbarSettingsPage,1);
357   -
358   - page->parent.load = load;
359   - page->parent.apply = apply;
360   - page->parent.label = _("Toolbar");
361   - page->parent.title = _("Setup toolbar");
362   -
363   - page->parent.widget = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
364   -
365   -
366   -
367   - return (Pw3270SettingsPage *) page;
368   - }
369   - */
... ...
src/objects/toolbar/toolbar.c
... ... @@ -38,71 +38,33 @@
38 38 static void get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
39 39 static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
40 40  
41   - const struct icon_size {
42   - const gchar * label;
43   - GtkIconSize icon_size;
44   - } icon_sizes[] = {
45   -
46   - {
47   - .label = N_( "System default" ),
48   - .icon_size = GTK_ICON_SIZE_INVALID
49   -
50   - },
51   -
52   - {
53   - .label = N_( "Small" ),
54   - .icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR
55   - },
56   -
57   - {
58   - .label = N_( "Large" ),
59   - .icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR
60   - },
61   - };
62   -
63   - static const struct style {
64   - const gchar * label;
65   - GtkToolbarStyle style;
66   - } styles[] = {
67   -
68   - {
69   - .label = N_( "System default" ),
70   - .style = GTK_TOOLBAR_DEFAULT_STYLE
71   - },
72   -
73   - {
74   - .label = N_( "Icons only" ),
75   - .style = GTK_TOOLBAR_ICONS
76   - },
77   -
78   - {
79   - .label = N_( "Text only" ),
80   - .style = GTK_TOOLBAR_TEXT
81   - },
82   -
83   - {
84   - .label = N_( "Icons & text" ),
85   - .style = GTK_TOOLBAR_BOTH
86   - },
87   - };
88   -
89 41 enum {
90 42 PROP_NONE,
91 43 PROP_ACTION_NAMES,
92 44 PROP_ICON_SIZE,
  45 + PROP_ICON_TYPE,
93 46 PROP_STYLE
94 47 };
95 48  
  49 + enum {
  50 + TOOLBAR_MENU_STYLE,
  51 + TOOLBAR_MENU_ICON_SIZE,
  52 + TOOLBAR_MENU_ICON_TYPE
  53 + };
  54 +
  55 + static const gchar * toolbar_menus[] = {
  56 + "toolbar-style",
  57 + "toolbar-icon-size",
  58 + "toolbar-icon-type"
  59 + };
  60 +
96 61 struct _pw3270ToolBar {
97 62 GtkToolbar parent;
98 63 GtkToolbarStyle style;
  64 + int icon_type;
99 65  
100   - /// @brief Popup Menu
101   - struct {
102   - GtkWidget * menu;
103   - GtkWidget * styles[G_N_ELEMENTS(styles)];
104   - GtkWidget * icon_sizes[G_N_ELEMENTS(icon_sizes)];
105   - } popup;
  66 + GtkWidget *menu;
  67 + GtkWidget *submenu[G_N_ELEMENTS(toolbar_menus)];
106 68  
107 69 };
108 70  
... ... @@ -131,9 +93,9 @@
131 93 object_class,
132 94 PROP_ACTION_NAMES,
133 95 g_param_spec_string (
134   - "action-names",
135   - N_("Action Names"),
136   - N_("The name of the actions in the toolbar"),
  96 + I_("action-names"),
  97 + "Action Names",
  98 + _("The name of the actions in the toolbar"),
137 99 NULL,
138 100 G_PARAM_READABLE|G_PARAM_WRITABLE)
139 101 );
... ... @@ -142,8 +104,8 @@
142 104 object_class,
143 105 PROP_ICON_SIZE,
144 106 g_param_spec_int(
145   - "icon-size",
146   - "icon-size",
  107 + I_("icon-size"),
  108 + "icon size",
147 109 _("The toolbar icon size"),
148 110 INT_MIN,
149 111 INT_MAX,
... ... @@ -155,7 +117,7 @@
155 117 object_class,
156 118 PROP_STYLE,
157 119 g_param_spec_int(
158   - "style",
  120 + I_("style"),
159 121 "style",
160 122 _("The toolbar style"),
161 123 INT_MIN,
... ... @@ -164,6 +126,19 @@
164 126 G_PARAM_READABLE|G_PARAM_WRITABLE)
165 127 );
166 128  
  129 + g_object_class_install_property(
  130 + object_class,
  131 + PROP_ICON_TYPE,
  132 + g_param_spec_int(
  133 + I_("icon-type"),
  134 + I_("icon-type"),
  135 + _("The toolbar icon type"),
  136 + 0,
  137 + 1,
  138 + 0,
  139 + G_PARAM_READABLE|G_PARAM_WRITABLE)
  140 + );
  141 +
167 142 }
168 143  
169 144 void get_property(GObject *object, guint prop_id, GValue *value, GParamSpec G_GNUC_UNUSED(*pspec)) {
... ... @@ -181,6 +156,10 @@
181 156 g_value_set_int(value,pw3270_toolbar_get_style(GTK_TOOLBAR(object)));
182 157 break;
183 158  
  159 + case PROP_ICON_TYPE:
  160 + g_value_set_int(value,pw3270_toolbar_get_icon_type(GTK_TOOLBAR(object)));
  161 + break;
  162 +
184 163 default:
185 164 g_assert_not_reached ();
186 165 }
... ... @@ -203,42 +182,27 @@
203 182 pw3270_toolbar_set_style(GTK_TOOLBAR(object),(GtkToolbarStyle) g_value_get_int(value));
204 183 break;
205 184  
  185 + case PROP_ICON_TYPE:
  186 + pw3270_toolbar_set_icon_type(GTK_TOOLBAR(object),(GtkToolbarStyle) g_value_get_int(value));
  187 + break;
  188 +
206 189 default:
207 190 g_assert_not_reached ();
208 191 }
209 192  
210 193 }
211 194  
212   -
213 195 static void detacher(GtkWidget *attach_widget, GtkMenu G_GNUC_UNUSED(*menu)) {
214 196  
215 197 pw3270ToolBar * toolbar = PW3270_TOOLBAR(attach_widget);
216   - toolbar->popup.menu = NULL;
217   -
218   - }
219   -
220   - static void set_icon_size(GtkCheckMenuItem *menuitem, GtkWidget *toolbar) {
221   -
222   - if(gtk_check_menu_item_get_active(menuitem)) {
223   - const struct icon_size * size = g_object_get_data(G_OBJECT(menuitem),"icon_size");
224   - pw3270_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), size->icon_size);
225   - }
  198 + toolbar->menu = NULL;
226 199  
227 200 }
228 201  
229   - static void set_style(GtkCheckMenuItem *menuitem, GtkWidget *toolbar) {
230   -
231   - if(gtk_check_menu_item_get_active(menuitem)) {
232   - struct style * style = g_object_get_data(G_OBJECT(menuitem),"toolbar_style");
233   - pw3270_toolbar_set_style(GTK_TOOLBAR(toolbar), style->style);
234   - }
235   -
236   - }
237   -
238   - static void open_properties(GtkMenuItem G_GNUC_UNUSED(*menuitem), GtkWidget *toolbar) {
  202 + static void open_preferences(GtkMenuItem G_GNUC_UNUSED(*menuitem), GtkWidget *toolbar) {
239 203  
240 204 GtkWidget * window = gtk_widget_get_toplevel(toolbar);
241   - GtkWidget * dialog = pw3270_settings_dialog_new(NULL);
  205 + GtkWidget * dialog = pw3270_settings_dialog_new(NULL,FALSE);
242 206  
243 207 gtk_container_add(GTK_CONTAINER(dialog),pw3270_toolbar_settings_new());
244 208  
... ... @@ -247,72 +211,36 @@
247 211 gtk_window_set_attached_to(GTK_WINDOW(dialog), window);
248 212 gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(window));
249 213  
  214 + gtk_window_set_title(GTK_WINDOW(dialog),_("Setup toolbar"));
  215 +
250 216 gtk_widget_show_all(dialog);
251 217  
252 218 }
253 219  
254 220 static void pw3270ToolBar_init(pw3270ToolBar *widget) {
255 221  
256   - widget->popup.menu = gtk_menu_new();
257   -
258   - // Size options
259   - {
260   - size_t ix;
261   -
262   - GtkWidget * item = gtk_menu_item_new_with_mnemonic( _("Icon _size") );
263   - gtk_menu_shell_append(GTK_MENU_SHELL(widget->popup.menu),item);
264   -
265   - GtkWidget * submenu = gtk_menu_new();
266   - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),submenu);
267   -
268   - for(ix = 0; ix < G_N_ELEMENTS(icon_sizes); ix++) {
269   -
270   - widget->popup.icon_sizes[ix] = item = gtk_check_menu_item_new_with_mnemonic(gettext(icon_sizes[ix].label));
271   - gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item),TRUE);
272   -
273   - g_object_set_data(G_OBJECT(item),"icon_size", (gpointer) &icon_sizes[ix]);
274   - g_signal_connect(item, "toggled", G_CALLBACK(set_icon_size), widget);
  222 + size_t ix;
275 223  
276   - gtk_menu_shell_append(GTK_MENU_SHELL(submenu),item);
  224 + widget->menu = gtk_menu_new();
277 225  
278   - }
279   -
280   - }
281   -
282   - // Style option
  226 + // Create menus.
283 227 {
284   - size_t ix;
285   -
286   - GtkWidget * item = gtk_menu_item_new_with_mnemonic( _("S_tyle") );
287   - gtk_menu_shell_append(GTK_MENU_SHELL(widget->popup.menu),item);
288   -
289   - GtkWidget * submenu = gtk_menu_new();
290   - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),submenu);
291   -
292   - for(ix = 0; ix < G_N_ELEMENTS(styles); ix++) {
293   -
294   - widget->popup.styles[ix] = item = gtk_check_menu_item_new_with_mnemonic(gettext(styles[ix].label));
295   - gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item),TRUE);
296   -
297   - g_object_set_data(G_OBJECT(item),"toolbar_style", (gpointer) &styles[ix]);
298   - g_signal_connect(item, "toggled", G_CALLBACK(set_style), widget);
299   -
300   - gtk_menu_shell_append(GTK_MENU_SHELL(submenu),item);
301   -
  228 + for(ix = 0; ix < G_N_ELEMENTS(widget->submenu); ix++) {
  229 + widget->submenu[ix] = pw3270_menu_item_from_model(GTK_WIDGET(widget),toolbar_menus[ix]);
  230 + gtk_menu_shell_append(GTK_MENU_SHELL(widget->menu),widget->submenu[ix]);
302 231 }
303   -
304 232 }
305 233  
306   - // Toolbar properties.
  234 + // Toolbar preferences.
307 235 {
308   - GtkWidget * item = gtk_menu_item_new_with_mnemonic( _("_Properties") );
309   - gtk_menu_shell_append(GTK_MENU_SHELL(widget->popup.menu),item);
310   - g_signal_connect(item, "activate", G_CALLBACK(open_properties), widget);
  236 + GtkWidget * item = gtk_menu_item_new_with_mnemonic( _("_Preferences") );
  237 + gtk_menu_shell_append(GTK_MENU_SHELL(widget->menu),gtk_separator_menu_item_new());
  238 + gtk_menu_shell_append(GTK_MENU_SHELL(widget->menu),item);
  239 + g_signal_connect(item, "activate", G_CALLBACK(open_preferences), widget);
311 240 }
312 241  
313   - // gtk_container_set_border_width(GTK_CONTAINER(widget->popup_menu),6);
314   - gtk_widget_show_all(widget->popup.menu);
315   - gtk_menu_attach_to_widget(GTK_MENU(widget->popup.menu),GTK_WIDGET(widget),detacher);
  242 + gtk_widget_show_all(widget->menu);
  243 + gtk_menu_attach_to_widget(GTK_MENU(widget->menu),GTK_WIDGET(widget),detacher);
316 244  
317 245 }
318 246  
... ... @@ -332,11 +260,11 @@
332 260  
333 261 debug("%s button_number=%d",__FUNCTION__,button_number);
334 262  
335   - if(toolbar->popup.menu) {
  263 + if(toolbar->menu) {
336 264 #if GTK_CHECK_VERSION(3,22,0)
337   - gtk_menu_popup_at_pointer(GTK_MENU(toolbar->popup.menu),NULL);
  265 + gtk_menu_popup_at_pointer(GTK_MENU(toolbar->menu),NULL);
338 266 #else
339   - gtk_menu_popup(GTK_MENU(toolbar->popup.menu), NULL, NULL, NULL, NULL, 0, 0);
  267 + gtk_menu_popup(GTK_MENU(toolbar->menu), NULL, NULL, NULL, NULL, 0, 0);
340 268 #endif
341 269 }
342 270  
... ... @@ -355,22 +283,6 @@
355 283 else
356 284 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),style);
357 285  
358   - // Update menu
359   - pw3270ToolBar * tb = PW3270_TOOLBAR(toolbar);
360   - if(tb && tb->popup.menu) {
361   - size_t ix;
362   - for(ix = 0; ix < G_N_ELEMENTS(styles); ix++) {
363   -
364   - gtk_check_menu_item_set_active(
365   - GTK_CHECK_MENU_ITEM(tb->popup.styles[ix]),
366   - styles[ix].style == style
367   - );
368   - }
369   - }
370   -
371   - // Store value
372   -// pw3270_settings_set_int("toolbar-style",(int) style);
373   -
374 286 g_object_notify(G_OBJECT(toolbar), "style");
375 287  
376 288 }
... ... @@ -379,6 +291,46 @@
379 291 return PW3270_TOOLBAR(toolbar)->style;
380 292 }
381 293  
  294 + gint pw3270_toolbar_get_icon_type(GtkToolbar *toolbar) {
  295 + return PW3270_TOOLBAR(toolbar)->icon_type;
  296 + }
  297 +
  298 + void pw3270_toolbar_set_icon_type(GtkToolbar *toolbar, gint icon_type) {
  299 +
  300 + if(PW3270_TOOLBAR(toolbar)->icon_type == icon_type)
  301 + return;
  302 +
  303 + PW3270_TOOLBAR(toolbar)->icon_type = icon_type;
  304 +
  305 + // Redefine icon types
  306 + GList * children = gtk_container_get_children(GTK_CONTAINER(toolbar));
  307 + GList * item;
  308 +
  309 + for(item = children;item;item = g_list_next(item)) {
  310 +
  311 + if(GTK_IS_TOOL_BUTTON(item->data)) {
  312 +
  313 + g_autofree gchar * icon_name = g_strdup(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(item->data)));
  314 + if(g_str_has_suffix(icon_name,"-symbolic")) {
  315 + icon_name[strlen(icon_name)-9] = 0;
  316 + }
  317 +
  318 + if(icon_type) {
  319 + g_autofree gchar * new_name = g_strconcat(icon_name,"-symbolic",NULL);
  320 + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item->data),new_name);
  321 + } else {
  322 + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item->data),icon_name);
  323 + }
  324 +
  325 + }
  326 +
  327 + }
  328 +
  329 + g_list_free(children);
  330 + g_object_notify(G_OBJECT(toolbar), "icon-type");
  331 +
  332 + }
  333 +
382 334 void pw3270_toolbar_set_icon_size(GtkToolbar *toolbar, GtkIconSize icon_size) {
383 335  
384 336 debug("%s(%d)",__FUNCTION__,(int) icon_size);
... ... @@ -388,19 +340,6 @@
388 340 else
389 341 gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar),icon_size);
390 342  
391   - // Update menu
392   - pw3270ToolBar * tb = PW3270_TOOLBAR(toolbar);
393   - if(tb && tb->popup.menu) {
394   - size_t ix;
395   - for(ix = 0; ix < G_N_ELEMENTS(icon_sizes); ix++) {
396   -
397   - gtk_check_menu_item_set_active(
398   - GTK_CHECK_MENU_ITEM(tb->popup.icon_sizes[ix]),
399   - icon_sizes[ix].icon_size == icon_size
400   - );
401   - }
402   - }
403   -
404 343 // Store value
405 344 g_object_notify(G_OBJECT(toolbar), "icon-size");
406 345  
... ... @@ -424,16 +363,46 @@
424 363  
425 364 void pw3270_toolbar_set_actions(GtkWidget *toolbar, const gchar *action_names) {
426 365  
427   - gchar ** actions = g_strsplit(action_names,",",-1);
428   - size_t ix;
  366 + size_t ix;
  367 + gint pos = 0;
  368 +
  369 + gchar ** blocks = g_strsplit(action_names,":",-1);
429 370  
430 371 gtk_container_remove_all(GTK_CONTAINER(toolbar));
431 372  
432   - for(ix = 0; actions[ix]; ix++) {
433   - pw3270_toolbar_insert_action(toolbar,actions[ix],-1);
  373 + // Left block
  374 + {
  375 + gchar ** actions = g_strsplit(blocks[0],",",-1);
  376 +
  377 + for(ix = 0; actions[ix]; ix++) {
  378 + pw3270_toolbar_insert_action(toolbar,actions[ix],pos++);
  379 + }
  380 +
  381 + g_strfreev(actions);
  382 +
  383 + }
  384 +
  385 + // Right block
  386 + if(blocks[1]) {
  387 +
  388 + GtkToolItem * item = gtk_separator_tool_item_new();
  389 +
  390 + gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(item),FALSE);
  391 + gtk_tool_item_set_expand(item,TRUE);
  392 + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item,pos++);
  393 +
  394 + gchar ** actions = g_strsplit(blocks[1],",",-1);
  395 +
  396 + for(ix = 0; actions[ix]; ix++) {
  397 + pw3270_toolbar_insert_action(toolbar,actions[ix],pos++);
  398 + }
  399 +
  400 + g_strfreev(actions);
  401 +
434 402 }
435 403  
436   - g_strfreev(actions);
  404 + g_strfreev(blocks);
  405 +
437 406  
438 407 g_object_notify(G_OBJECT(toolbar), "action-names");
439 408  
... ... @@ -464,71 +433,3 @@
464 433 return g_string_free(str,FALSE);
465 434 }
466 435  
467   - GtkTreeModel * pw3270_toolbar_style_model_new() {
468   -
469   - size_t ix;
470   - GtkTreeIter iter;
471   - GtkListStore * model = gtk_list_store_new(2, G_TYPE_STRING,G_TYPE_UINT);
472   -
473   - for(ix = 0; ix < G_N_ELEMENTS(icon_sizes); ix++) {
474   - gtk_list_store_append(model,&iter);
475   - gtk_list_store_set( model,
476   - &iter,
477   - 0, gettext(styles[ix].label),
478   - 1, (guint) styles[ix].style,
479   - -1);
480   -
481   - }
482   -
483   - return GTK_TREE_MODEL(model);
484   -
485   - }
486   -
487   - GtkTreeModel * pw3270_toolbar_icon_size_model_new() {
488   -
489   - size_t ix;
490   - GtkTreeIter iter;
491   - GtkListStore * model = gtk_list_store_new(2, G_TYPE_STRING,G_TYPE_UINT);
492   -
493   - for(ix = 0; ix < G_N_ELEMENTS(icon_sizes); ix++) {
494   - gtk_list_store_append(model,&iter);
495   - gtk_list_store_set( model,
496   - &iter,
497   - 0, gettext(icon_sizes[ix].label),
498   - 1, (guint) icon_sizes[ix].icon_size,
499   - -1);
500   -
501   - }
502   -
503   - return GTK_TREE_MODEL(model);
504   - }
505   -
506   - void pw3270_model_get_iter_from_value(GtkTreeModel * model, GtkTreeIter *iter, guint value) {
507   -
508   - if(gtk_tree_model_get_iter_first(model,iter)) {
509   -
510   - do {
511   -
512   - GValue gVal = { 0, };
513   - gtk_tree_model_get_value(model,iter,1,&gVal);
514   - guint iVal = g_value_get_uint(&gVal);
515   - g_value_unset(&gVal);
516   -
517   - if(iVal == value) {
518   - return;
519   - }
520   -
521   - } while(gtk_tree_model_iter_next(model,iter));
522   -
523   - }
524   -
525   - }
526   -
527   - guint pw3270_model_get_value_from_iter(GtkTreeModel * model, GtkTreeIter *iter) {
528   - GValue gVal = { 0, };
529   - gtk_tree_model_get_value(model,iter,1,&gVal);
530   - guint iVal = g_value_get_uint(&gVal);
531   - g_value_unset(&gVal);
532   - return iVal;
533   -}
534   -
... ...
src/objects/window/actions/sessionproperties.c
... ... @@ -33,6 +33,7 @@
33 33 #include <v3270/settings.h>
34 34 #include <v3270/dialogs.h>
35 35 #include <v3270/colorscheme.h>
  36 + #include <pw3270/application.h>
36 37  
37 38 static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
38 39  
... ... @@ -42,7 +43,8 @@
42 43  
43 44 action->name = "session.properties";
44 45 action->icon_name = "preferences-other";
45   - action->label = _("Session properties");
  46 + action->label = _("Session preferences");
  47 + action->tooltip = _("Change the preferences for the active session");
46 48  
47 49 return G_ACTION(action);
48 50 }
... ... @@ -52,7 +54,6 @@
52 54 size_t ix;
53 55  
54 56 GtkWidget * dialog = v3270_settings_dialog_new();
55   -
56 57 gtk_window_set_title(GTK_WINDOW(dialog), action->label);
57 58  
58 59 // Add settings pages.
... ... @@ -68,6 +69,12 @@
68 69 gtk_container_add(GTK_CONTAINER(dialog), elements[ix]);
69 70 }
70 71  
  72 + pw3270_application_plugin_call(
  73 + g_application_get_default(),
  74 + "pw3270_plugin_set_session_properties",
  75 + dialog
  76 + );
  77 +
71 78 // Setup dialog box
72 79 gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(gtk_widget_get_toplevel(terminal)));
73 80 gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
... ...
src/objects/window/header-settings.c 0 → 100644
... ... @@ -0,0 +1,174 @@
  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 "private.h"
  31 + #include <pw3270.h>
  32 + #include <pw3270/actions.h>
  33 + #include <pw3270/settings.h>
  34 + #include <pw3270/application.h>
  35 + #include <v3270/dialogs.h>
  36 +
  37 + static void load(GtkWidget *widget, PW3270SettingsPrivate *settings);
  38 + static void apply(GtkWidget *widget, PW3270SettingsPrivate *settings);
  39 +
  40 +/*--[ Constants ]------------------------------------------------------------------------------------*/
  41 +
  42 + struct _PW3270SettingsPrivate {
  43 + GtkWidget * editor;
  44 + /*
  45 + GtkWidget * views[3];
  46 + GtkTreeModel * model;
  47 + */
  48 + };
  49 +
  50 + /*
  51 + static const struct _views {
  52 + const char * label;
  53 + gint left;
  54 + gint top;
  55 + gint height;
  56 + } views[] = {
  57 + {
  58 + .label = N_("Left"),
  59 + .left = 0,
  60 + .top = 0,
  61 + .height = 4
  62 + },
  63 + {
  64 + .label = N_("Right"),
  65 + .left = 0,
  66 + .top = 6,
  67 + .height = 4
  68 + },
  69 + {
  70 + .label = N_("Available"),
  71 + .left = 2,
  72 + .top = 0,
  73 + .height = 10
  74 + }
  75 + };
  76 + */
  77 +
  78 + /*--[ Implement ]------------------------------------------------------------------------------------*/
  79 +
  80 + GtkWidget * pw3270_header_settings_new() {
  81 +
  82 + size_t ix;
  83 +
  84 + // Create page widget.
  85 + PW3270Settings * settings = pw3270_settings_new();
  86 + settings->label = _("Title bar");
  87 + settings->title = _("Setup title bar");
  88 + settings->apply = apply;
  89 + settings->load = load;
  90 +
  91 + // Create private data.
  92 + PW3270SettingsPrivate * page = settings->settings = g_new0(PW3270SettingsPrivate,1);
  93 +
  94 + page->editor = pw3270_settings_actions_new();
  95 +
  96 + gtk_grid_attach(
  97 + GTK_GRID(settings),
  98 + v3270_dialog_section_new(_("Title bar actions"), _("Change the position of the title bar icons"), page->editor),
  99 + 0,0,4,3
  100 + );
  101 +
  102 +
  103 + gtk_widget_show_all(GTK_WIDGET(settings));
  104 + return GTK_WIDGET(settings);
  105 + }
  106 +
  107 + void load(GtkWidget *widget, PW3270SettingsPrivate *page) {
  108 +
  109 + g_autoptr(GSettings) settings = pw3270_application_window_settings_new();
  110 +
  111 + // Get avaliable actions.
  112 + Pw3270ActionList * action_list = pw3270_action_list_new(GTK_APPLICATION(g_application_get_default()));
  113 +
  114 + // Add standard menus
  115 + {
  116 + static const struct menu {
  117 + const gchar * action_name;
  118 + const gchar * label;
  119 + const gchar * icon_name;
  120 + } menus[] = {
  121 + {
  122 + .action_name = "menu.open-menu",
  123 + .label = N_("Application menu"),
  124 + .icon_name = "open-menu-symbolic"
  125 + }
  126 + };
  127 +
  128 + size_t ix;
  129 +
  130 + for(ix = 0; ix < G_N_ELEMENTS(menus); ix++) {
  131 +
  132 + GError *error = NULL;
  133 +
  134 + GdkPixbuf * pixbuf = gtk_icon_theme_load_icon(
  135 + gtk_icon_theme_get_default(),
  136 + menus[ix].icon_name,
  137 + GTK_ICON_SIZE_MENU,
  138 + GTK_ICON_LOOKUP_GENERIC_FALLBACK,
  139 + &error
  140 + );
  141 +
  142 + if(error) {
  143 + g_warning(error->message);
  144 + g_error_free(error);
  145 + error = NULL;
  146 + }
  147 +
  148 + action_list = pw3270_action_list_append(
  149 + action_list,
  150 + gettext(menus[ix].label),
  151 + pixbuf,
  152 + menus[ix].action_name,
  153 + PW3270_ACTION_VIEW_ALLOW_MOVE
  154 + );
  155 + }
  156 +
  157 + }
  158 +
  159 + // Load settings
  160 + g_autofree gchar * action_names = g_settings_get_string(settings,"header-action-names");
  161 +
  162 + action_list = pw3270_settings_action_set(page->editor, action_list, action_names);
  163 +
  164 + pw3270_action_list_free(action_list);
  165 + }
  166 +
  167 + void apply(GtkWidget *widget, PW3270SettingsPrivate *page) {
  168 +
  169 + g_autofree gchar * action_names = pw3270_settings_action_get(page->editor);
  170 + g_autoptr(GSettings) settings = pw3270_application_window_settings_new();
  171 + g_settings_set_string(settings,"header-action-names",action_names);
  172 +
  173 + }
  174 +
... ...
src/objects/window/header.c
... ... @@ -112,9 +112,20 @@
112 112  
113 113 }
114 114  
  115 + static GAction * get_action_from_name(GtkWidget *widget, const gchar *action_name) {
  116 +
  117 + if(g_str_has_prefix(action_name,"app.")) {
  118 + return g_action_map_lookup_action(G_ACTION_MAP(g_application_get_default()),action_name+4);
  119 + }
  120 +
  121 + return g_action_map_lookup_action(G_ACTION_MAP(widget),action_name+4);
  122 + }
  123 +
115 124 GtkWidget * pw3270_header_button_new_from_builder(GtkWidget *widget, GtkBuilder * builder, const gchar *action_name) {
116 125  
117 126 GtkWidget * button = NULL;
  127 + g_autoptr(GSettings) settings = pw3270_application_window_settings_new();
  128 + gboolean symbolic = g_settings_get_int(settings,"header-icon-type") == 1;
118 129  
119 130 if(g_str_has_prefix(action_name,"menu.")) {
120 131  
... ... @@ -127,45 +138,33 @@
127 138 gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(button), G_MENU_MODEL(gtk_builder_get_object(builder, action_name+5)));
128 139 gtk_widget_set_visible(button,TRUE);
129 140  
130   - } else if(g_str_has_prefix(action_name,"app.")) {
131   -
132   - // It's an application action
133   -
134   - } else if(g_str_has_prefix(action_name,"win.")) {
135   -
136   - // It's a window action.
137   - GAction * action = g_action_map_lookup_action(G_ACTION_MAP(widget),action_name+4);
138   -
139   - if(action) {
140 141  
141   - button = gtk_button_new_from_action(action,GTK_ICON_SIZE_BUTTON);
142   -
143   - gtk_actionable_set_action_name(GTK_ACTIONABLE(button),action_name);
144   - gtk_widget_set_visible(button,g_action_get_enabled(action));
145   -
146   -
147   - } else {
  142 + } else {
148 143  
149   - g_warning("Can't find action \"%s\"",action_name+4);
  144 + GAction * action = get_action_from_name(widget,action_name);
150 145  
  146 + if(!action) {
  147 + g_warning("Can't find action %s",action_name);
  148 + return NULL;
151 149 }
152 150  
153   - }
  151 + button = gtk_button_new_from_action(action,GTK_ICON_SIZE_BUTTON,symbolic);
154 152  
155   - if(button) {
  153 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button),action_name);
  154 + gtk_widget_set_visible(button,g_action_get_enabled(action));
156 155  
157   - g_signal_connect(button, "notify::sensitive", G_CALLBACK(on_sensitive), widget);
158   - gtk_widget_set_focus_on_click(button,FALSE);
159   - gtk_widget_set_can_focus(button,FALSE);
160   - gtk_widget_set_can_default(button,FALSE);
161   - gtk_widget_set_name(button,action_name);
162   -
163   - } else {
164   -
165   - g_warning("Can't create button for action \"%s\"",action_name);
  156 + g_autofree gchar * tooltip = g_action_get_tooltip(action);
  157 + if(tooltip)
  158 + gtk_widget_set_tooltip_markup(GTK_WIDGET(button),tooltip);
166 159  
167 160 }
168 161  
  162 + g_signal_connect(button, "notify::sensitive", G_CALLBACK(on_sensitive), widget);
  163 + gtk_widget_set_focus_on_click(button,FALSE);
  164 + gtk_widget_set_can_focus(button,FALSE);
  165 + gtk_widget_set_can_default(button,FALSE);
  166 + gtk_widget_set_name(button,action_name);
  167 +
169 168 return button;
170 169 }
171 170  
... ...
src/objects/window/keyfile.c 0 → 100644
... ... @@ -0,0 +1,366 @@
  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 <config.h>
  31 + #include <glib.h>
  32 + #include <glib/gstdio.h>
  33 + #include <fcntl.h>
  34 + #include <sys/types.h>
  35 + #include <sys/stat.h>
  36 + #include <lib3270.h>
  37 + #include <lib3270/log.h>
  38 + #include <v3270.h>
  39 + #include <v3270/settings.h>
  40 + #include <v3270/keyfile.h>
  41 + #include <v3270/actions.h>
  42 + #include <lib3270/properties.h>
  43 + #include <string.h>
  44 + #include <stdlib.h>
  45 +
  46 + struct _V3270KeyFile
  47 + {
  48 + gboolean changed; ///< @brief Save file?
  49 + GKeyFile * key_file;
  50 + gchar filename[1];
  51 + };
  52 +
  53 + static V3270KeyFile * v3270_get_session_descriptor(GtkWidget *terminal) {
  54 +
  55 + return (V3270KeyFile *) g_object_get_data(G_OBJECT(terminal),"session-descriptor");
  56 +
  57 + }
  58 +
  59 + static void close_keyfile(V3270KeyFile * session) {
  60 +
  61 + if(session->key_file) {
  62 +
  63 + if(session->changed) {
  64 + g_message("Saving file %s",session->filename);
  65 + g_key_file_save_to_file(session->key_file,session->filename,NULL);
  66 + session->changed = FALSE;
  67 + } else {
  68 + g_message("Closing file %s",session->filename);
  69 + }
  70 +
  71 + g_key_file_free(session->key_file);
  72 + session->key_file = NULL;
  73 + }
  74 +
  75 + g_free(session);
  76 + }
  77 +
  78 + V3270KeyFile * v3270_key_file_open(GtkWidget *terminal, const gchar *filename, GError **error) {
  79 +
  80 + g_return_val_if_fail(GTK_IS_V3270(terminal),FALSE);
  81 + g_return_val_if_fail(*error == NULL,FALSE);
  82 +
  83 + V3270KeyFile * new_session = (V3270KeyFile *) g_malloc0(sizeof(struct _V3270KeyFile) + strlen(filename));
  84 + V3270KeyFile * old_session = g_object_get_data(G_OBJECT(terminal),"session-descriptor");
  85 +
  86 + // Clone session
  87 + if(old_session) {
  88 + *new_session = *old_session;
  89 + }
  90 +
  91 + strcpy(new_session->filename,filename);
  92 + new_session->key_file = g_key_file_new();
  93 +
  94 + // Load file
  95 + if(g_file_test(new_session->filename,G_FILE_TEST_IS_REGULAR)) {
  96 +
  97 + // Found session file, open it.
  98 + if(!g_key_file_load_from_file(new_session->key_file,new_session->filename,G_KEY_FILE_NONE,error)) {
  99 + g_warning("Can't load \"%s\"",new_session->filename);
  100 + } else {
  101 + g_message("Loading session preferences from %s",new_session->filename);
  102 + }
  103 +
  104 + } else {
  105 +
  106 + // No session file, load the defaults (if available) and save file
  107 + lib3270_autoptr(char) default_settings = lib3270_build_data_filename("defaults.conf",NULL);
  108 +
  109 + if(g_file_test(default_settings,G_FILE_TEST_IS_REGULAR)) {
  110 + if(!g_key_file_load_from_file(new_session->key_file,default_settings,G_KEY_FILE_NONE,error)) {
  111 + g_warning("Can't load \"%s\"",default_settings);
  112 + } else {
  113 + g_message("Loading session preferences from %s",default_settings);
  114 + }
  115 + } else {
  116 +#ifdef DEBUG
  117 + g_message("Can't find default settings file \"%s\"",default_settings);
  118 +#else
  119 + g_warning("Can't find default settings file \"%s\"",default_settings);
  120 +#endif // DEBUG
  121 + }
  122 +
  123 + new_session->changed = TRUE;
  124 +
  125 + }
  126 +
  127 + g_object_set_data_full(G_OBJECT(terminal),"session-descriptor",new_session,(GDestroyNotify) close_keyfile);
  128 + if(new_session->changed) {
  129 + v3270_key_file_save(terminal,error);
  130 + }
  131 +
  132 + if(!*error) {
  133 +
  134 + // Got key file, load it.
  135 + v3270_load_key_file(terminal,new_session->key_file,NULL);
  136 + v3270_accelerator_map_load_key_file(terminal,new_session->key_file,NULL);
  137 +
  138 + if(g_key_file_has_group(new_session->key_file,"environment")) {
  139 +
  140 + // Has environment group, set values.
  141 + gchar **keys = g_key_file_get_keys(new_session->key_file,"environment",NULL,NULL);
  142 +
  143 + if(keys) {
  144 + size_t ix;
  145 + for(ix=0;keys[ix];ix++) {
  146 + g_autofree gchar * value = g_key_file_get_string(new_session->key_file,"environment",keys[ix],NULL);
  147 + if(value) {
  148 +#ifdef _WIN32
  149 + g_autofree gchar * env = g_strconcat(keys[ix],"=",value,NULL);
  150 + putenv(env);
  151 +#else
  152 + if(setenv(keys[ix],value,1)) {
  153 + g_warning("Can't set \"%s\" to \"%s\"",keys[ix],value);
  154 + }
  155 +#endif // _WIN32
  156 + }
  157 + }
  158 +
  159 + g_strfreev(keys);
  160 + }
  161 + }
  162 +
  163 + }
  164 +
  165 + return new_session;
  166 +}
  167 +
  168 +void v3270_key_file_close(GtkWidget *terminal) {
  169 +
  170 + V3270KeyFile *session = g_object_get_data(G_OBJECT(terminal),"session-descriptor");
  171 +
  172 + if(session->key_file) {
  173 +
  174 + if(session->changed) {
  175 + g_message("Saving file %s",session->filename);
  176 + g_key_file_save_to_file(session->key_file,session->filename,NULL);
  177 + session->changed = FALSE;
  178 + } else {
  179 + g_message("Closing file %s",session->filename);
  180 + }
  181 +
  182 + g_key_file_free(session->key_file);
  183 + session->key_file = NULL;
  184 + }
  185 +
  186 + }
  187 +
  188 + GKeyFile * v3270_key_file_get(GtkWidget *terminal) {
  189 + return v3270_get_session_descriptor(terminal)->key_file;
  190 + }
  191 +
  192 + void v3270_key_file_save_to_file(GtkWidget * terminal, const gchar *filename, GError **error) {
  193 +
  194 + if(error && *error)
  195 + return;
  196 +
  197 + V3270KeyFile * new_session = (V3270KeyFile *) g_malloc0(sizeof(struct _V3270KeyFile) + strlen(filename));
  198 + V3270KeyFile * old_session = g_object_get_data(G_OBJECT(terminal),"session-descriptor");
  199 +
  200 + if(old_session) {
  201 + *new_session = *old_session;
  202 + }
  203 +
  204 + strcpy(new_session->filename,filename);
  205 + new_session->key_file = g_key_file_new();
  206 +
  207 + g_object_set_data_full(G_OBJECT(terminal),"session-descriptor",new_session,(GDestroyNotify) close_keyfile);
  208 + v3270_key_file_save(terminal,error);
  209 +
  210 + }
  211 +
  212 + void v3270_key_file_save(GtkWidget *terminal, GError **error) {
  213 +
  214 + if(error && *error)
  215 + return;
  216 +
  217 + V3270KeyFile *session = v3270_get_session_descriptor(terminal);
  218 +
  219 + session->changed = FALSE;
  220 +
  221 + debug("%s: terminal=%p session=%p key-file=%p)",__FUNCTION__,terminal,session,session->key_file);
  222 +
  223 + v3270_to_key_file(terminal,session->key_file,"terminal");
  224 + v3270_accelerator_map_to_key_file(terminal, session->key_file, "accelerators");
  225 +
  226 + g_key_file_save_to_file(session->key_file,session->filename,NULL);
  227 +
  228 + }
  229 +
  230 + /// @brief Search standard paths.
  231 + gchar * v3270_key_file_get_default_path(GtkWidget *terminal) {
  232 +
  233 + size_t folder;
  234 + const gchar *folders[] = {
  235 + g_get_user_data_dir(),
  236 + g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS),
  237 + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)
  238 + };
  239 +
  240 + size_t application;
  241 + const gchar *applications[] = {
  242 + G_STRINGIFY(PRODUCT_NAME),
  243 + PACKAGE_NAME,
  244 + "3270",
  245 + "tn3270"
  246 + };
  247 +
  248 + for(folder = 0; folder < G_N_ELEMENTS(folders); folder++) {
  249 +
  250 + if(!(folders[folder] && g_file_test(folders[folder],G_FILE_TEST_IS_DIR)))
  251 + continue;
  252 +
  253 + for(application = 0; application < G_N_ELEMENTS(applications); application++) {
  254 +
  255 + gchar * appdir = g_build_filename(folder[folders],application[applications],NULL);
  256 +
  257 + debug("Testing for \"%s\"",appdir);
  258 + if(g_file_test(appdir,G_FILE_TEST_IS_DIR)) {
  259 + return appdir;
  260 + }
  261 + g_free(appdir);
  262 +
  263 + }
  264 +
  265 + }
  266 +
  267 + // Not found, try the current session path.
  268 + const gchar * filename = v3270_key_file_get_filename(terminal);
  269 + debug("Testing for \"%s\"",filename);
  270 + if(filename
  271 + && g_file_test(filename,G_FILE_TEST_IS_REGULAR)
  272 + && g_str_has_prefix(filename,g_get_user_data_dir())
  273 + && !g_str_has_prefix(filename,g_get_user_config_dir())
  274 + ) {
  275 + return g_path_get_dirname(filename);
  276 + }
  277 +
  278 + return g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS));
  279 +
  280 + }
  281 +
  282 + gchar * v3270_keyfile_get_default_filename(void) {
  283 +
  284 + gchar * filename = g_build_filename(g_get_user_config_dir(),"default.3270",NULL);
  285 +
  286 + g_autofree gchar * compatible = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME) ".conf",NULL);
  287 + if(g_file_test(compatible,G_FILE_TEST_IS_REGULAR))
  288 + g_rename(compatible,filename);
  289 +
  290 + return filename;
  291 + }
  292 +
  293 + gchar * v3270_key_file_build_filename(GtkWidget *terminal) {
  294 +
  295 + g_autofree gchar * defname = v3270_keyfile_get_default_filename();
  296 + const gchar * current = v3270_key_file_get_filename(terminal);
  297 +
  298 + // If is not the default name, return it.
  299 + if(current && *current && g_file_test(current,G_FILE_TEST_IS_REGULAR) && strcmp(defname,current)) {
  300 + return g_strdup(current);
  301 + }
  302 +
  303 + g_autofree gchar * folder = v3270_key_file_get_default_path(terminal);
  304 +
  305 + const char * hostname = lib3270_host_get_name(v3270_get_session(terminal));
  306 + debug("Hostname=\"%s\"",hostname);
  307 +
  308 + gchar * name = g_strconcat(folder,G_DIR_SEPARATOR_S,(hostname ? hostname : "session"),".3270",NULL);
  309 + unsigned int index = 0;
  310 + while(g_file_test(name,G_FILE_TEST_EXISTS)) {
  311 + g_free(name);
  312 + name = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.%u.3270",folder,hostname,++index);
  313 + }
  314 +
  315 + debug("%s returns \"%s\"",__FUNCTION__,name);
  316 +
  317 + return name;
  318 + }
  319 +
  320 + const gchar * v3270_key_file_get_filename(GtkWidget *terminal) {
  321 +
  322 + V3270KeyFile *session = v3270_get_session_descriptor(terminal);
  323 +
  324 + if(session && *session->filename)
  325 + return session->filename;
  326 +
  327 + return NULL;
  328 +
  329 + }
  330 +
  331 + void v3270_key_file_set_boolean(GtkWidget *terminal, const gchar *group_name, const gchar *key, gboolean value) {
  332 +
  333 + V3270KeyFile *session = v3270_get_session_descriptor(terminal);
  334 + g_key_file_set_boolean(session->key_file,group_name ? group_name : "terminal",key,value);
  335 + session->changed = TRUE;
  336 +
  337 +}
  338 +
  339 + gboolean v3270_key_file_can_write(GtkWidget *widget) {
  340 +
  341 +#if defined(DEBUG)
  342 +
  343 + return TRUE;
  344 +
  345 +#else
  346 +
  347 + const V3270KeyFile * descriptor = v3270_get_session_descriptor(widget);
  348 +
  349 + if(!(descriptor && *descriptor->filename))
  350 + return FALSE;
  351 +
  352 + if(g_access(descriptor->filename,W_OK))
  353 + return FALSE;
  354 +
  355 +#ifdef _WIN32
  356 + return TRUE;
  357 +#else
  358 + return !g_str_has_prefix(descriptor->filename,g_get_user_config_dir());
  359 +#endif // _WIN32
  360 +
  361 +#endif // DEBUG
  362 +
  363 + }
  364 +
  365 +
  366 +
... ...
src/objects/window/page.c
... ... @@ -35,6 +35,7 @@
35 35 #include <v3270/dialogs.h>
36 36 #include <v3270/actions.h>
37 37 #include <v3270/print.h>
  38 + #include <v3270/keyfile.h>
38 39 #include <pw3270.h>
39 40  
40 41 //---[ Gtk Label with customized popup-menu ]---------------------------------------------------------------------------------------
... ... @@ -302,30 +303,6 @@
302 303 // Show dialog.
303 304 gtk_widget_show_all(dialog);
304 305  
305   -
306   -
307   - /*
308   - GtkWidget * dialog = pw3270_settings_dialog_new(
309   - _("Rename session"),
310   - GTK_WINDOW(gtk_widget_get_toplevel(terminal))
311   - );
312   -
313   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
314   - gtk_container_set_border_width(GTK_CONTAINER(content),18);
315   -
316   -
317   - gtk_widget_show_all(dialog);
318   -
319   - if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_APPLY) {
320   -
321   - v3270_set_session_name(terminal, gtk_entry_get_text(GTK_ENTRY(entry)));
322   - g_signal_emit_by_name(terminal,"save-settings");
323   -
324   - }
325   -
326   - gtk_widget_destroy(dialog);
327   - */
328   -
329 306 }
330 307  
331 308 static gboolean terminal_popup(GtkWidget *widget, gboolean selected, gboolean online, GdkEvent *event, pw3270ApplicationWindow * window) {
... ... @@ -387,7 +364,7 @@
387 364 {
388 365 .label = N_("_Rename session"),
389 366 .callback = G_CALLBACK(rename_session),
390   - .check_permission = v3270_allow_custom_settings
  367 + .check_permission = v3270_key_file_can_write
391 368 },
392 369  
393 370 {
... ...
src/objects/window/private.h
... ... @@ -90,7 +90,7 @@
90 90 G_GNUC_INTERNAL GAction * pw3270_file_transfer_action_new(void);
91 91 G_GNUC_INTERNAL GAction * pw3270_action_window_close_new(void);
92 92 G_GNUC_INTERNAL GAction * pw3270_action_connect_new(void);
93   - G_GNUC_INTERNAL GAction * pw3270_action_save_session_as_new(void);
  93 + G_GNUC_INTERNAL GAction * pw3270_action_save_session_preferences_new(void);
94 94 G_GNUC_INTERNAL GAction * pw3270_action_save_desktop_icon_new(void);
95 95  
96 96 GAction * pw3270_action_session_properties_new(void);
... ...
src/objects/window/terminal.c
... ... @@ -40,82 +40,24 @@
40 40 #include <lib3270/toggle.h>
41 41 #include <v3270/settings.h>
42 42 #include <v3270/actions.h>
  43 + #include <v3270/keyfile.h>
43 44 #include <v3270/print.h>
  45 + #include <lib3270/os.h>
44 46  
45   - struct SessionDescriptor
46   - {
47   - gboolean changed; ///< @brief Save file?
48   - GKeyFile * key_file;
49   - gchar filename[1];
50   - };
51   -
52   - static void destroy(GtkWidget G_GNUC_UNUSED(*terminal), struct SessionDescriptor * session) {
53   -
54   - if(session->changed) {
55   -
56   - session->changed = FALSE;
57   -
58   - GError * error = NULL;
59   - g_key_file_save_to_file(session->key_file,session->filename,&error);
60   -
61   - if(error) {
62   -
63   - g_warning("Can't save \"%s\": %s",session->filename,error->message);
64   - g_error_free(error);
65   -
66   - } else {
67   -
68   - g_message("Session was saved to %s",session->filename);
69   -
70   - }
71   -
72   - }
73   -
  47 + static void destroy(GtkWidget *terminal, gpointer G_GNUC_UNUSED(dunno)) {
  48 + v3270_key_file_close(terminal);
74 49 }
75 50  
76   - static void save_settings(GtkWidget *terminal, struct SessionDescriptor * session) {
77   -
78   - session->changed = FALSE;
79   -
80   - debug("%s(%p,%p)",__FUNCTION__,terminal,session);
81   -
82   - v3270_to_key_file(terminal,session->key_file,"terminal");
83   - v3270_accelerator_map_to_key_file(terminal, session->key_file, "accelerators");
84   -
85   - /*
86   - GtkWidget * window = gtk_widget_get_toplevel(terminal);
87   -
88   - if(PW3270_IS_APPLICATION_WINDOW(window) && pw3270_application_window_get_active_terminal(window) == terminal) {
89   -
90   - debug("%s on active terminal, saving window settings",__FUNCTION__);
91   - GList * keypad = pw3270_application_window_get_keypads(window);
92   -
93   - while(keypad) {
94   -
95   - g_key_file_set_boolean(
96   - session->key_file,
97   - "keypads",
98   - gtk_widget_get_name(GTK_WIDGET(keypad->data)),
99   - gtk_widget_get_visible(GTK_WIDGET(keypad->data))
100   - );
101   - keypad = g_list_next(keypad);
102   -
103   - }
104   -
105   - }
106   - */
107   -
108   - g_key_file_save_to_file(session->key_file,session->filename,NULL);
109   -
  51 + static void toggle_changed(GtkWidget *widget, LIB3270_TOGGLE_ID G_GNUC_UNUSED(toggle_id), gboolean toggle_state, const gchar *toggle_name, gpointer G_GNUC_UNUSED(dunno)) {
  52 + debug("%s(%s)=%s",__FUNCTION__,toggle_name,toggle_state ? "ON" : "OFF");
  53 + v3270_key_file_set_boolean(widget,"terminal",toggle_name,toggle_state);
110 54 }
111 55  
112   - static void toggle_changed(G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED LIB3270_TOGGLE_ID toggle_id, gboolean toggle_state, const gchar *toggle_name, struct SessionDescriptor * session) {
113   - debug("%s(%s)=%s",__FUNCTION__,toggle_name,toggle_state ? "ON" : "OFF");
114   - g_key_file_set_boolean(session->key_file,"terminal",toggle_name,toggle_state);
115   - session->changed = TRUE;
  56 + static void save_settings(GtkWidget *terminal, gpointer G_GNUC_UNUSED(dunno)) {
  57 + v3270_key_file_save(terminal,NULL);
116 58 }
117 59  
118   - static void print_done(G_GNUC_UNUSED GtkWidget *widget, GtkPrintOperation *operation, GtkPrintOperationResult result, struct SessionDescriptor * session) {
  60 + static void print_done(GtkWidget *widget, GtkPrintOperation *operation, GtkPrintOperationResult result, gpointer G_GNUC_UNUSED(dunno)) {
119 61 debug("%s(%u)",__FUNCTION__,(unsigned int) result);
120 62  
121 63 if(result != GTK_PRINT_OPERATION_RESULT_APPLY)
... ... @@ -123,250 +65,113 @@
123 65  
124 66 debug("%s: Saving print settings",__FUNCTION__);
125 67  
126   - v3270_print_operation_to_key_file(operation,session->key_file);
  68 + v3270_print_operation_to_key_file(operation,v3270_key_file_get(widget));
  69 + v3270_emit_save_settings(widget,NULL);
127 70  
128   - g_key_file_save_to_file(session->key_file,session->filename,NULL);
129   - session->changed = FALSE;
130 71 }
131 72  
132   - static void print_setup(G_GNUC_UNUSED GtkWidget *widget, GtkPrintOperation *operation, struct SessionDescriptor * session) {
  73 + static void print_setup(G_GNUC_UNUSED GtkWidget *widget, GtkPrintOperation *operation, gpointer G_GNUC_UNUSED(dunno) ) {
133 74  
134 75 debug("%s(%p)",__FUNCTION__,operation);
135   - v3270_print_operation_load_key_file(operation,session->key_file);
  76 + v3270_print_operation_load_key_file(operation,v3270_key_file_get(widget));
136 77  
137 78 }
138 79  
139   - static void close_settings(struct SessionDescriptor * session) {
  80 + static GtkResponseType load_popup_response(GtkWidget *widget, const gchar *popup_name, gpointer G_GNUC_UNUSED(dunno)) {
140 81  
141   - if(session->key_file) {
  82 + GKeyFile * key_file = v3270_key_file_get(widget);
142 83  
143   - if(session->changed) {
144   - g_message("Saving file %s",session->filename);
145   - g_key_file_save_to_file(session->key_file,session->filename,NULL);
146   - session->changed = FALSE;
147   - } else {
148   - g_message("Closing file %s",session->filename);
149   - }
  84 + if(key_file && g_key_file_has_key(key_file,"dialogs",popup_name,NULL))
  85 + return (GtkResponseType) g_key_file_get_integer(key_file,"dialogs",popup_name,NULL);
150 86  
151   - g_key_file_free(session->key_file);
152   - session->key_file = NULL;
153   - }
154   -
155   - g_free(session);
156   - }
157   -
158   - const gchar * v3270_get_session_filename(GtkWidget *widget) {
159   -
160   - g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
161   -
162   - const struct SessionDescriptor * descriptor = (const struct SessionDescriptor *) g_object_get_data(G_OBJECT(widget),"session-descriptor");
163   -
164   - if(descriptor)
165   - return descriptor->filename;
166   -
167   - return NULL;
168   - }
169   -
170   - void v3270_set_session_filename(GtkWidget *terminal, const gchar *filename) {
171   -
172   - struct SessionDescriptor * old_session = (struct SessionDescriptor *) g_object_get_data(G_OBJECT(terminal),"session-descriptor");
173   - struct SessionDescriptor * new_session = (struct SessionDescriptor *) g_malloc0(sizeof(struct SessionDescriptor) + strlen(filename));
174   -
175   - if(old_session) {
176   - memcpy(new_session,old_session,sizeof(struct SessionDescriptor));
177   - }
178   -
179   - strcpy(new_session->filename,filename);
180   - new_session->key_file = g_key_file_new();
181   -
182   - v3270_to_key_file(terminal,new_session->key_file,NULL);
183   - v3270_accelerator_map_to_key_file(terminal,new_session->key_file,NULL);
184   -
185   - GError *error = NULL;
186   - g_key_file_save_to_file(new_session->key_file,new_session->filename,&error);
187   -
188   - if(error) {
189   -
190   - g_message("Can't save file \"%s\": %s",new_session->filename,error->message);
191   -
192   - GtkWidget * dialog = gtk_message_dialog_new_with_markup(
193   - GTK_WINDOW(gtk_widget_get_toplevel(terminal)),
194   - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
195   - GTK_MESSAGE_ERROR,
196   - GTK_BUTTONS_CANCEL,
197   - _("Can't save file \"%s\""),new_session->filename
198   - );
199   -
200   - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",error->message);
201   -
202   - gtk_window_set_title(GTK_WINDOW(dialog),_("Can't save session file"));
203   -
204   - gtk_widget_show_all(dialog);
205   -
206   - g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL);
207   - g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
  87 +#ifdef _WIN32
  88 + {
  89 + // Windows - Check predefined responses on system registry.
  90 + lib3270_auto_cleanup(HKEY) hKey;
208 91  
209   - g_error_free(error);
210   - g_key_file_free(new_session->key_file);
211   - g_free(new_session);
  92 + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,G_STRINGIFY(PRODUCT_NAME)"\\dialogs",0,KEY_READ,&hKey) == ERROR_SUCCESS) {
212 93  
213   - } else {
  94 + DWORD val = 0;
  95 + DWORD cbData = sizeof(DWORD);
214 96  
215   - new_session->changed = FALSE;
216   - g_object_set_data_full(G_OBJECT(terminal),"session-descriptor",new_session,(GDestroyNotify) close_settings);
  97 + if(RegQueryValueEx(hKey, popup_name, NULL, NULL, (LPBYTE) &val, &cbData) == ERROR_SUCCESS) {
  98 + return (GtkResponseType) val;
  99 + }
217 100  
  101 + }
218 102 }
  103 +#endif // _WIN32
219 104  
220   -
221   - }
222   -
223   - GKeyFile * v3270_get_session_keyfile(GtkWidget *widget) {
224   -
225   - g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
226   -
227   - const struct SessionDescriptor * descriptor = (const struct SessionDescriptor *) g_object_get_data(G_OBJECT(widget),"session-descriptor");
228   -
229   - if(descriptor)
230   - return descriptor->key_file;
231   -
232   - return NULL;
  105 + return key_file ? GTK_RESPONSE_NONE : 0;
233 106 }
234 107  
235   - static GtkResponseType load_popup_response(v3270 G_GNUC_UNUSED(*widget), const gchar *popup_name, struct SessionDescriptor * session) {
  108 + static gboolean save_popup_response(GtkWidget *widget, const gchar *popup_name, GtkResponseType response, gpointer G_GNUC_UNUSED(dunno)) {
236 109  
237   - if(!session->key_file)
238   - return 0;
  110 + GKeyFile * key_file = v3270_key_file_get(widget);
239 111  
240   - if(g_key_file_has_key(session->key_file,"dialogs",popup_name,NULL))
241   - return (GtkResponseType) g_key_file_get_integer(session->key_file,"dialogs",popup_name,NULL);
242   -
243   - return GTK_RESPONSE_NONE;
244   - }
  112 + debug("%s(%s)",__FUNCTION__,popup_name);
245 113  
246   - static gboolean save_popup_response(GtkWidget *widget, const gchar *popup_name, GtkResponseType response, struct SessionDescriptor * session) {
247   - debug("%s(%s)",__FUNCTION__,popup_name);
248   -
249   - if(!session->key_file)
250   - return FALSE;
  114 + if(!key_file)
  115 + return FALSE;
251 116  
252   - g_key_file_set_integer(session->key_file,"dialogs",popup_name,(gint) response);
253   - v3270_emit_save_settings(widget,NULL);
  117 + g_key_file_set_integer(key_file,"dialogs",popup_name,(gint) response);
  118 + v3270_emit_save_settings(widget,NULL);
254 119  
255   - return TRUE;
  120 + return TRUE;
256 121 }
257 122  
258 123 GtkWidget * pw3270_terminal_new(const gchar *session_file) {
259 124  
260   - GtkWidget * terminal = v3270_new();
  125 + GtkWidget * terminal = v3270_new();
  126 + GError * error = NULL;
261 127  
262 128 gtk_widget_show_all(terminal);
263 129  
264   - struct SessionDescriptor * descriptor = NULL;
265   -
266 130 if(session_file) {
267 131  
268 132 // Use the supplied session file
269   - descriptor = g_malloc0(sizeof(struct SessionDescriptor) + strlen(session_file));
270   - strcpy(descriptor->filename,session_file);
  133 + v3270_key_file_open(terminal,session_file,&error);
271 134  
272 135 } else {
273 136  
274 137 // No session file, use the default one.
275   - g_autofree gchar * compatible = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME) ".conf",NULL);
276   - g_autofree gchar * filename = g_build_filename(g_get_user_config_dir(),"default.3270",NULL);
277   -
278   - if(g_file_test(compatible,G_FILE_TEST_IS_REGULAR))
279   - {
280   - g_rename(compatible,filename);
281   - }
282   -
283   - descriptor = g_malloc0(sizeof(struct SessionDescriptor) + strlen(filename));
284   - strcpy(descriptor->filename,filename);
  138 + gchar * filename = v3270_keyfile_get_default_filename();
  139 + v3270_key_file_open(terminal,filename,&error);
  140 + g_free(filename);
285 141  
286 142 }
287 143  
288   - // Setup session file;
289   - GError *error = NULL;
290   - g_object_set_data_full(G_OBJECT(terminal),"session-descriptor",descriptor,(GDestroyNotify) close_settings);
291   -
292   - descriptor->key_file = g_key_file_new();
  144 + // Setup signals.
  145 + g_signal_connect(G_OBJECT(terminal),"save-settings",G_CALLBACK(save_settings),NULL);
  146 + g_signal_connect(G_OBJECT(terminal),"toggle_changed",G_CALLBACK(toggle_changed),NULL);
  147 + g_signal_connect(G_OBJECT(terminal),"print-done",G_CALLBACK(print_done),NULL);
  148 + g_signal_connect(G_OBJECT(terminal),"print-setup",G_CALLBACK(print_setup),NULL);
  149 + g_signal_connect(G_OBJECT(terminal),"destroy", G_CALLBACK(destroy),NULL);
  150 + g_signal_connect(G_OBJECT(terminal),"load-popup-response",G_CALLBACK(load_popup_response),NULL);
  151 + g_signal_connect(G_OBJECT(terminal),"save-popup-response",G_CALLBACK(save_popup_response),NULL);
293 152  
294   - if(g_file_test(descriptor->filename,G_FILE_TEST_IS_REGULAR)) {
  153 + if(error) {
295 154  
296   - // Found session file, open it.
297   - if(!g_key_file_load_from_file(descriptor->key_file,descriptor->filename,G_KEY_FILE_NONE,&error)) {
298   - g_warning("Can't load \"%s\"",descriptor->filename);
299   - } else {
300   - g_message("Loading session properties from %s",descriptor->filename);
301   - }
  155 + GtkWidget * dialog = gtk_message_dialog_new_with_markup(
  156 + GTK_WINDOW(gtk_widget_get_toplevel(terminal)),
  157 + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
  158 + GTK_MESSAGE_ERROR,
  159 + GTK_BUTTONS_CANCEL,
  160 + _("Can't use \"%s\""),session_file
  161 + );
302 162  
303   - } else {
  163 + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",error->message);
304 164  
305   - // No session file, load the defaults (if available).
306   - lib3270_autoptr(char) default_settings = lib3270_build_data_filename("defaults.conf",NULL);
307   - if(g_file_test(default_settings,G_FILE_TEST_IS_REGULAR)) {
308   - if(!g_key_file_load_from_file(descriptor->key_file,default_settings,G_KEY_FILE_NONE,&error)) {
309   - g_warning("Can't load \"%s\"",default_settings);
310   - } else {
311   - g_message("Loading session properties from %s",default_settings);
312   - }
313   - } else {
314   -#ifdef DEBUG
315   - g_message("Can't find default settings file \"%s\"",default_settings);
316   -#else
317   - g_warning("Can't find default settings file \"%s\"",default_settings);
318   -#endif // DEBUG
319   - }
  165 + gtk_window_set_title(GTK_WINDOW(dialog),_("Can't load session file"));
320 166  
321   - }
  167 + gtk_widget_show_all(dialog);
322 168  
323   - if(error) {
  169 + g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL);
  170 + g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
324 171  
325   - g_warning(error->message);
326 172 g_error_free(error);
327   - error = NULL;
328   -
329   - } else {
330   -
331   - // Got key file, load it.
332   - v3270_load_key_file(terminal,descriptor->key_file,NULL);
333   - v3270_accelerator_map_load_key_file(terminal,descriptor->key_file,NULL);
334   -
335   - if(g_key_file_has_group(descriptor->key_file,"environment")) {
336   -
337   - // Has environment group, set values.
338   - gchar **keys = g_key_file_get_keys(descriptor->key_file,"environment",NULL,NULL);
339   -
340   - if(keys) {
341   - size_t ix;
342   - for(ix=0;keys[ix];ix++) {
343   - g_autofree gchar * value = g_key_file_get_string(descriptor->key_file,"environment",keys[ix],NULL);
344   - if(value) {
345   -#ifdef _WIN32
346   - g_autofree gchar * env = g_strconcat(keys[ix],"=",value,NULL);
347   - putenv(env);
348   -#else
349   - if(setenv(keys[ix],value,1)) {
350   - g_warning("Can't set \"%s\" to \"%s\"",keys[ix],value);
351   - }
352   -#endif // _WIN32
353   - }
354   - }
355   -
356   - g_strfreev(keys);
357   - }
358   - }
359 173 }
360 174  
361   - // Setup signals.
362   - g_signal_connect(G_OBJECT(terminal),"save-settings",G_CALLBACK(save_settings),descriptor);
363   - g_signal_connect(G_OBJECT(terminal),"toggle_changed",G_CALLBACK(toggle_changed),descriptor);
364   - g_signal_connect(G_OBJECT(terminal),"print-done",G_CALLBACK(print_done),descriptor);
365   - g_signal_connect(G_OBJECT(terminal),"print-setup",G_CALLBACK(print_setup),descriptor);
366   - g_signal_connect(G_OBJECT(terminal),"destroy", G_CALLBACK(destroy),descriptor);
367   - g_signal_connect(G_OBJECT(terminal),"load-popup-response",G_CALLBACK(load_popup_response),descriptor);
368   - g_signal_connect(G_OBJECT(terminal),"save-popup-response",G_CALLBACK(save_popup_response),descriptor);
369   -
370 175 return terminal;
371 176 }
372 177  
... ... @@ -382,30 +187,4 @@
382 187  
383 188 }
384 189  
385   - gboolean v3270_allow_custom_settings(GtkWidget *widget) {
386   -
387   -#if defined(DEBUG)
388   -
389   - return TRUE;
390   -
391   -#else
392   -
393   - const struct SessionDescriptor * descriptor = (const struct SessionDescriptor *) g_object_get_data(G_OBJECT(widget),"session-descriptor");
394   -
395   - if(!(descriptor && *descriptor->filename))
396   - return FALSE;
397   -
398   - if(g_access(descriptor->filename,W_OK))
399   - return FALSE;
400   -
401   -#ifdef _WIN32
402   - return TRUE;
403   -#else
404   - return !g_str_has_prefix(descriptor->filename,g_get_user_config_dir());
405   -#endif // _WIN32
406   -
407   -#endif // DEBUG
408   -
409   - }
410   -
411 190  
... ...
src/objects/window/window.c
... ... @@ -34,6 +34,7 @@
34 34 #include <pw3270/actions.h>
35 35 #include <pw3270/keypad.h>
36 36 #include <v3270/settings.h>
  37 + #include <v3270/keyfile.h>
37 38  
38 39 static void get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
39 40 static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
... ... @@ -142,6 +143,26 @@
142 143  
143 144 static void pw3270ApplicationWindow_class_init(pw3270ApplicationWindowClass *klass) {
144 145  
  146 +#ifdef DEBUG
  147 + {
  148 + gtk_icon_theme_append_search_path(
  149 + gtk_icon_theme_get_default(),
  150 + "./icons"
  151 + );
  152 + }
  153 +#else
  154 + {
  155 + lib3270_autoptr(char) path = lib3270_build_data_filename("icons",NULL);
  156 + if(g_file_test(path,G_FILE_TEST_IS_DIR)) {
  157 + gtk_icon_theme_append_search_path(
  158 + gtk_icon_theme_get_default(),
  159 + path
  160 + );
  161 + }
  162 + }
  163 +#endif // DEBUG
  164 +
  165 +
145 166 {
146 167 GtkWidgetClass *widget = GTK_WIDGET_CLASS(klass);
147 168 widget->destroy = destroy;
... ... @@ -191,8 +212,8 @@
191 212 if(!terminal)
192 213 return;
193 214  
194   - GKeyFile * keyfile = v3270_get_session_keyfile(terminal);
195   - if(!terminal)
  215 + GKeyFile * keyfile = v3270_key_file_get(terminal);
  216 + if(!keyfile)
196 217 return;
197 218  
198 219 g_key_file_set_boolean(
... ... @@ -251,6 +272,16 @@
251 272  
252 273 static void pw3270ApplicationWindow_init(pw3270ApplicationWindow *widget) {
253 274  
  275 + // Get settings
  276 + g_autoptr(GSettings) settings = pw3270_application_window_settings_new();
  277 +
  278 + // Override defaults
  279 + {
  280 + // https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/gtksettings.c
  281 + GtkSettings *settings = gtk_widget_get_settings(GTK_WIDGET (widget));
  282 + g_object_set(settings,"gtk-menu-bar-accel","",NULL);
  283 + }
  284 +
254 285 // Setup defaults
255 286 widget->state.width = 800;
256 287 widget->state.height = 500;
... ... @@ -282,17 +313,86 @@
282 313 gtk_notebook_set_action_widget(widget->notebook,new_tab,GTK_PACK_START);
283 314 }
284 315  
285   - widget->toolbar = GTK_TOOLBAR(pw3270_toolbar_new());
286   - gtk_box_pack_start(container,GTK_WIDGET(widget->toolbar),FALSE,TRUE,0);
  316 + // Create boxes
  317 + GtkBox * hBox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0));
  318 + GtkBox * vBox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL,0));
  319 +
  320 + gtk_widget_show(GTK_WIDGET(hBox));
  321 + gtk_widget_show(GTK_WIDGET(vBox));
  322 +
  323 + // Create toolbar
  324 + {
  325 + widget->toolbar = GTK_TOOLBAR(pw3270_toolbar_new());
  326 +
  327 + g_action_map_add_action(
  328 + G_ACTION_MAP(widget),
  329 + G_ACTION(g_property_action_new("toolbar", widget->toolbar, "visible"))
  330 + );
  331 +
  332 + switch(g_settings_get_int(settings,"toolbar-position")) {
  333 + case 1:
  334 + gtk_orientable_set_orientation(GTK_ORIENTABLE(widget->toolbar),GTK_ORIENTATION_HORIZONTAL);
  335 + gtk_box_pack_end(container,GTK_WIDGET(widget->toolbar),FALSE,TRUE,0);
  336 + break;
  337 +
  338 + case 2:
  339 + gtk_orientable_set_orientation(GTK_ORIENTABLE(widget->toolbar),GTK_ORIENTATION_VERTICAL);
  340 + gtk_box_pack_end(hBox,GTK_WIDGET(widget->toolbar),FALSE,TRUE,0);
  341 + break;
  342 +
  343 + case 3:
  344 + gtk_orientable_set_orientation(GTK_ORIENTABLE(widget->toolbar),GTK_ORIENTATION_VERTICAL);
  345 + gtk_box_pack_start(hBox,GTK_WIDGET(widget->toolbar),FALSE,TRUE,0);
  346 + break;
  347 +
  348 + default:
  349 + gtk_orientable_set_orientation(GTK_ORIENTABLE(widget->toolbar),GTK_ORIENTATION_HORIZONTAL);
  350 + gtk_box_pack_start(container,GTK_WIDGET(widget->toolbar),FALSE,TRUE,0);
  351 + break;
  352 +
  353 + }
  354 +
  355 + g_settings_bind(
  356 + settings,
  357 + "toolbar-visible",
  358 + widget->toolbar,
  359 + "visible",
  360 + G_SETTINGS_BIND_DEFAULT
  361 + );
  362 +
  363 + g_settings_bind(
  364 + settings,
  365 + "toolbar-icon-type",
  366 + widget->toolbar,
  367 + "icon-type",
  368 + G_SETTINGS_BIND_DEFAULT
  369 + );
  370 +
  371 + g_settings_bind(
  372 + settings,
  373 + "toolbar-style",
  374 + widget->toolbar,
  375 + "style",
  376 + G_SETTINGS_BIND_DEFAULT
  377 + );
  378 +
  379 + g_settings_bind(
  380 + settings,
  381 + "toolbar-icon-size",
  382 + widget->toolbar,
  383 + "icon-size",
  384 + G_SETTINGS_BIND_DEFAULT
  385 + );
  386 +
  387 + }
  388 +
  389 + gtk_box_pack_start(container,GTK_WIDGET(hBox),TRUE,TRUE,0);
287 390  
288 391 //
289   - // Do we have keypads?
  392 + // Create and pack keypads?
290 393 //
291   - GList * keypads = pw3270_application_get_keypad_models(g_application_get_default());
292   - if(keypads) {
293   -
294   - GtkBox * hBox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0));
295   - GtkBox * vBox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL,0));
  394 + {
  395 + GList * keypads = pw3270_application_get_keypad_models(g_application_get_default());
296 396 GList * keypad;
297 397  
298 398 // Add top Keypads
... ... @@ -349,15 +449,6 @@
349 449 }
350 450 }
351 451  
352   - // Add it to the container
353   - gtk_widget_show(GTK_WIDGET(hBox));
354   - gtk_widget_show(GTK_WIDGET(vBox));
355   - gtk_box_pack_start(container,GTK_WIDGET(hBox),TRUE,TRUE,0);
356   -
357   - } else {
358   -
359   - gtk_box_pack_start(container,GTK_WIDGET(widget->notebook),TRUE,TRUE,0);
360   -
361 452 }
362 453  
363 454 gtk_widget_show_all(GTK_WIDGET(widget->notebook));
... ... @@ -381,7 +472,7 @@
381 472 pw3270_action_session_properties_new(),
382 473 pw3270_set_color_action_new(),
383 474  
384   - pw3270_action_save_session_as_new(),
  475 + pw3270_action_save_session_preferences_new(),
385 476  
386 477 pw3270_file_transfer_action_new(),
387 478  
... ... @@ -409,22 +500,21 @@
409 500 }
410 501  
411 502 //
412   - // Setup toolbar
  503 + // Bind properties
413 504 //
  505 + g_action_map_add_action(
  506 + G_ACTION_MAP(widget),
  507 + G_ACTION(g_property_action_new("menubar", widget, "show-menubar"))
  508 + );
414 509  
415   - {
416   -
417   - g_action_map_add_action(
418   - G_ACTION_MAP(widget),
419   - G_ACTION(g_property_action_new("toolbar", widget->toolbar, "visible"))
420   - );
421   -
422   - g_action_map_add_action(
423   - G_ACTION_MAP(widget),
424   - G_ACTION(g_property_action_new("menubar", widget, "show-menubar"))
425   - );
  510 + g_settings_bind(
  511 + settings,
  512 + "toolbar-action-names",
  513 + widget->toolbar,
  514 + "action-names",
  515 + G_SETTINGS_BIND_DEFAULT
  516 + );
426 517  
427   - }
428 518  
429 519 }
430 520  
... ... @@ -567,38 +657,6 @@
567 657 G_SETTINGS_BIND_DEFAULT
568 658 );
569 659  
570   - g_settings_bind(
571   - settings,
572   - "toolbar-visible",
573   - window->toolbar,
574   - "visible",
575   - G_SETTINGS_BIND_DEFAULT
576   - );
577   -
578   - g_settings_bind(
579   - settings,
580   - "toolbar-action-names",
581   - window->toolbar,
582   - "action-names",
583   - G_SETTINGS_BIND_DEFAULT
584   - );
585   -
586   - g_settings_bind(
587   - settings,
588   - "toolbar-style",
589   - window->toolbar,
590   - "style",
591   - G_SETTINGS_BIND_DEFAULT
592   - );
593   -
594   - g_settings_bind(
595   - settings,
596   - "toolbar-icon-size",
597   - window->toolbar,
598   - "icon-size",
599   - G_SETTINGS_BIND_DEFAULT
600   - );
601   -
602 660 }
603 661  
604 662 // Setup default position and size
... ... @@ -704,7 +762,7 @@
704 762 // Setup keypads
705 763 if(window->keypads) {
706 764  
707   - GKeyFile * keyfile = v3270_get_session_keyfile(terminal);
  765 + GKeyFile * keyfile = v3270_key_file_get(terminal);
708 766  
709 767 if(keyfile) {
710 768  
... ...
src/objects/windows/savedesktopicon.c
... ... @@ -1,176 +0,0 @@
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   - /**
31   - * @brief Implement Windows version of the save desktop icon action.
32   - *
33   - * References:
34   - *
35   - * <https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32>
36   - * <https://docs.microsoft.com/pt-br/windows/win32/shell/links?redirectedfrom=MSDN>
37   - *
38   - */
39   -
40   - #include <winsock2.h>
41   - #include <windows.h>
42   -
43   - #include <v3270.h>
44   - #include <pw3270.h>
45   - #include <pw3270/application.h>
46   - #include <v3270/actions.h>
47   - #include <lib3270.h>
48   - #include <lib3270/log.h>
49   -
50   - static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal);
51   - static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal);
52   -
53   - static const struct _entry {
54   -
55   - const gchar * label;
56   - const gchar * tooltip;
57   - gint width;
58   -
59   - } entries[] = {
60   -
61   - {
62   - .label = N_("File name"),
63   - .width = 40,
64   - },
65   -
66   - {
67   - .label = N_("Launcher name"),
68   - .width = 20,
69   - }
70   -
71   - };
72   -
73   - GAction * pw3270_action_save_desktop_icon_new(void) {
74   -
75   - V3270SimpleAction * action = v3270_dialog_action_new(factory);
76   -
77   - action->name = "save.launcher";
78   - action->label = _("Save desktop icon");
79   - action->tooltip = _("Create a desktop icon for the current session");
80   -
81   - return G_ACTION(action);
82   -
83   - }
84   -
85   - GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) {
86   -
87   - size_t ix;
88   -
89   - gboolean use_header;
90   - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
91   -
92   - GtkWidget * dialog =
93   - GTK_WIDGET(g_object_new(
94   - GTK_TYPE_DIALOG,
95   - "use-header-bar", (use_header ? 1 : 0),
96   - NULL
97   - ));
98   -
99   - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
100   - gtk_window_set_title(GTK_WINDOW(dialog),action->label);
101   -
102   - gtk_dialog_add_buttons(
103   - GTK_DIALOG(dialog),
104   - _("_Cancel"), GTK_RESPONSE_CANCEL,
105   - _("_Save"), GTK_RESPONSE_APPLY,
106   - NULL
107   - );
108   -
109   - g_signal_connect(dialog,"response",G_CALLBACK(response),terminal);
110   -
111   - // Create entry fields
112   - GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries));
113   - g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free);
114   - debug("Dialog=%p inputs=%p",dialog,inputs);
115   -
116   - GtkGrid * grid = GTK_GRID(gtk_grid_new());
117   -
118   - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0);
119   -
120   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
121   - gtk_container_set_border_width(GTK_CONTAINER(grid),18);
122   - gtk_grid_set_row_spacing(GTK_GRID(grid),6);
123   - gtk_grid_set_column_spacing(GTK_GRID(grid),12);
124   -
125   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
126   - // gtk_box_set_spacing(GTK_BOX(content_area),18);
127   -
128   - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) {
129   -
130   - GtkWidget * label = gtk_label_new(gettext(entries[ix].label));
131   - gtk_label_set_xalign(GTK_LABEL(label),1);
132   - gtk_grid_attach(grid,label,0,ix,1,1);
133   -
134   - inputs[ix] = gtk_entry_new();
135   - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]);
136   -
137   - gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width);
138   -// gtk_entry_set_max_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].n_chars);
139   - gtk_widget_set_hexpand(inputs[ix],FALSE);
140   - gtk_widget_set_vexpand(inputs[ix],FALSE);
141   -
142   - gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1);
143   -
144   - }
145   -
146   - /*
147   -
148   - gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename);
149   -
150   - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));
151   - gtk_entry_set_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME));
152   -
153   - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));
154   - gtk_entry_set_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME));
155   -
156   - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));
157   - gtk_entry_set_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal));
158   - gtk_entry_set_input_hints(GTK_ENTRY(inputs[3]),GTK_INPUT_HINT_SPELLCHECK);
159   -
160   - */
161   -
162   - gtk_widget_show_all(GTK_WIDGET(grid));
163   - return dialog;
164   - }
165   -
166   - void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) {
167   -
168   - debug("%s(%d)",__FUNCTION__,response_id);
169   -
170   - if(response_id == GTK_RESPONSE_APPLY) {
171   -
172   - }
173   -
174   - gtk_widget_destroy(dialog);
175   -
176   -}
ui/application.xml
... ... @@ -155,12 +155,12 @@
155 155 <section>
156 156  
157 157 <item>
158   - <attribute name="label" translatable="yes">Desktop icon</attribute>
  158 + <attribute name="label" translatable="yes">Shortcut for this session</attribute>
159 159 <attribute name="action">win.save.launcher</attribute>
160 160 </item>
161 161  
162 162 <item>
163   - <attribute name="label" translatable="yes">Session properties</attribute>
  163 + <attribute name="label" translatable="yes">Session preferences</attribute>
164 164 <attribute name="action">win.save.session.as</attribute>
165 165 </item>
166 166  
... ...
ui/window.xml
... ... @@ -90,13 +90,13 @@
90 90 <section>
91 91  
92 92 <item>
93   - <attribute name="label" translatable="yes">Desktop icon</attribute>
  93 + <attribute name="label" translatable="yes">Shortcut for this session</attribute>
94 94 <attribute name="action">win.save.launcher</attribute>
95 95 </item>
96 96  
97 97 <item>
98   - <attribute name="label" translatable="yes">Session properties</attribute>
99   - <attribute name="action">win.save.session.as</attribute>
  98 + <attribute name="label" translatable="yes">Session preferences</attribute>
  99 + <attribute name="action">win.save.session.preferences</attribute>
100 100 </item>
101 101  
102 102 </section>
... ... @@ -165,6 +165,16 @@
165 165 </item>
166 166  
167 167 <item>
  168 + <attribute name="label" translatable="yes">Copy as HTML</attribute>
  169 + <attribute name="action">win.copy-html</attribute>
  170 + </item>
  171 +
  172 + <item>
  173 + <attribute name="label" translatable="yes">Copy as image</attribute>
  174 + <attribute name="action">win.copy-pixbuff</attribute>
  175 + </item>
  176 +
  177 + <item>
168 178 <attribute name="label" translatable="yes">Append to copy</attribute>
169 179 <attribute name="action">win.copy-append</attribute>
170 180 </item>
... ... @@ -361,6 +371,11 @@
361 371 </item>
362 372  
363 373 <item>
  374 + <attribute name="label" translatable="yes">Use +/- for field navigation</attribute>
  375 + <attribute name="action">win.kpalternative</attribute>
  376 + </item>
  377 +
  378 + <item>
364 379 <attribute name="label" translatable="yes">Resize on alternate screen</attribute>
365 380 <attribute name="action">win.altscreen</attribute>
366 381 </item>
... ... @@ -381,7 +396,7 @@
381 396 <attribute name="label" translatable="yes">Dynamic font spacing</attribute>
382 397 <attribute name="action">win.dynamic-font-spacing</attribute>
383 398 </item>
384   -
  399 +
385 400 <section>
386 401  
387 402 <item>
... ... @@ -426,6 +441,11 @@
426 441 <attribute name="action">win.menubar</attribute>
427 442 </item>
428 443  
  444 + <item>
  445 + <attribute name="label" translatable="yes">Session Trace</attribute>
  446 + <attribute name="action">win.trace</attribute>
  447 + </item>
  448 +
429 449 </submenu>
430 450  
431 451 <section>
... ... @@ -460,7 +480,7 @@
460 480 </item>
461 481  
462 482 </section>
463   -
  483 +
464 484 </menu>
465 485  
466 486 <menu id="popup-over-oia">
... ... @@ -527,7 +547,7 @@
527 547  
528 548 </submenu>
529 549  
530   - <submenu id="view-when-offline-placeholder">
  550 + <submenu id="view-when-offline-placeholder">
531 551  
532 552 <attribute name='label' translatable='yes'>View</attribute>
533 553  
... ... @@ -541,6 +561,11 @@
541 561 <attribute name="action">win.menubar</attribute>
542 562 </item>
543 563  
  564 + <item>
  565 + <attribute name="label" translatable="yes">Session Trace</attribute>
  566 + <attribute name="action">win.trace</attribute>
  567 + </item>
  568 +
544 569 </submenu>
545 570  
546 571 <section>
... ... @@ -551,7 +576,7 @@
551 576 </item>
552 577  
553 578 <item>
554   - <attribute name="label" translatable="yes">Session properties</attribute>
  579 + <attribute name="label" translatable="yes">Session preferences</attribute>
555 580 <attribute name="action">win.session.properties</attribute>
556 581 </item>
557 582  
... ...
win/gtk.css 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +/* Disable F10 */
  2 +@binding-set NoKeyboardNavigation {
  3 + unbind "<shift>F10"
  4 + unbind "F10"
  5 +}
  6 +
  7 +* {
  8 + -gtk-key-bindings: NoKeyboardNavigation
  9 +}
  10 +
... ...
win/makeruntime.sh.in
... ... @@ -25,6 +25,9 @@
25 25 # erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
26 26 #
27 27  
  28 +# Get myDIR
  29 +myDIR=$(dirname $(readlink -f "${0}"))
  30 +
28 31 # Disable i18n
29 32 export LANG=C
30 33  
... ... @@ -286,6 +289,11 @@ copy_theme() {
286 289 exit -1
287 290 fi
288 291  
  292 + echo "${myDIR}/gtk.css"
  293 + if [ -e "${myDIR}/gtk.css" ]; then
  294 + cp "${myDIR}/gtk.css" "${TARGET}/share/themes/${1}/gtk-3.0/gtk.css"
  295 + fi
  296 +
289 297 }
290 298  
291 299 #
... ...
win/pack.sh
... ... @@ -31,10 +31,14 @@ LIBRARY_NAME=&quot;lib3270&quot;
31 31 CORE_LIBRARIES="lib3270 libv3270 libipc3270"
32 32 PACKAGE_PLUGINS=""
33 33 PACKAGE_EXTRAS="libhllapi"
34   -TARGET_ARCHS="x86_64 x86_32"
  34 +
  35 +#TARGET_ARCHS="x86_64 x86_32"
  36 +TARGET_ARCHS="x86_64"
  37 +
35 38 GIT_URL="https://github.com/PerryWerneck"
36 39 BUILD_UNSTABLE=0
37 40 MAKE_ZIP=0
  41 +CLEAR_TARGET_PATH=0
38 42  
39 43 PROJECTDIR=$(dirname $(dirname $(readlink -f ${0})))
40 44 WORKDIR=$(mktemp -d)
... ... @@ -80,7 +84,6 @@ failed()
80 84 clone()
81 85 {
82 86 echo -e "\e]2;Cloning ${1}\a"
83   - echo "Cloning ${1}"
84 87  
85 88 mkdir -p ${WORKDIR}/sources
86 89  
... ... @@ -552,27 +555,40 @@ makeRuntime()
552 555 #
553 556 copy_install_file() {
554 557  
555   - FILENAME=${PROJECTDIR}/$(basename ${1})
556   -
557   - rm -f "${FILENAME}"
558   - cp -v "${1}" "${FILENAME}"
559   -
560 558 if [ "$?" != "0" ]; then
561 559 failed "Can't copy ${1} to ${FILENAME}"
562 560 fi
563 561  
564 562 if [ ${BUILD_UNSTABLE} == "1" ]; then
565 563 TARGET_PATH="/${PRODUCT_NAME}/unstable/${ARCH}"
  564 + FILENAME=${PROJECTDIR}/dist/unstable/${ARCH}/$(basename ${1})
566 565 else
567 566 TARGET_PATH="/${PRODUCT_NAME}/stable/${ARCH}"
  567 + FILENAME=${PROJECTDIR}/dist/stable/${ARCH}/$(basename ${1})
568 568 fi
569 569  
  570 + if [ "${CLEAR_TARGET_PATH}" == "1" ]; then
  571 + rm -fr "$(dirname ${FILENAME})/*"
  572 + fi
  573 +
  574 + mkdir -p $(dirname ${FILENAME})
  575 + ln -f -v "${1}" "${FILENAME}"
  576 + if [ "$?" != "0" ]; then
  577 + cp -v "${1}" "${FILENAME}"
  578 + fi
  579 +
570 580 if [ -d ~/public_html/win/${PRODUCT_NAME} ]; then
571   - mkdir -p ~/public_html/win/${TARGET_PATH}
572   - ln -f -v "${FILENAME}" ~/public_html/win/${TARGET_PATH}
  581 +
  582 + mkdir -p "~/public_html/win/${TARGET_PATH}"
573 583 if [ "$?" != "0" ]; then
574   - failed "Can't link ${1} to ~/public_html/win/${TARGET_PATH}"
  584 + failed "Can't create ~/public_html/win/${TARGET_PATH}"
  585 + fi
  586 +
  587 + if [ "${CLEAR_TARGET_PATH}" == "1" ]; then
  588 + rm -fr ~/public_html/win/${TARGET_PATH}/*
575 589 fi
  590 +
  591 + ln -f -v "${FILENAME}" ~/public_html/win/${TARGET_PATH}
576 592 fi
577 593  
578 594 if [ ! -z "${XDG_PUBLICSHARE_DIR}" ] && [ -d "${XDG_PUBLICSHARE_DIR}/${PRODUCT_NAME}" ]; then
... ... @@ -582,18 +598,21 @@ copy_install_file() {
582 598 failed "Can't create ${XDG_PUBLICSHARE_DIR}/${TARGET_PATH}"
583 599 fi
584 600  
585   - ln -f -v "${FILENAME}" ${XDG_PUBLICSHARE_DIR}/${TARGET_PATH}
586   - if [ "$?" != "0" ]; then
587   - failed "Can't link ${1} to ~/${XDG_PUBLICSHARE_DIR}/${TARGET_PATH}"
  601 + if [ "${CLEAR_TARGET_PATH}" == "1" ]; then
  602 + rm -fr ${XDG_PUBLICSHARE_DIR}/${TARGET_PATH}/*
588 603 fi
589 604  
  605 + ln -f -v "${FILENAME}" ${XDG_PUBLICSHARE_DIR}/${TARGET_PATH}
  606 +
590 607 fi
591 608  
592   - if [ "${PUBLISH}" == "1" ] && [ ! -z ${WIN_PACKAGE_SERVER} ]; then
  609 + if [ "${PUBLISH}" == "1" ] && [ ! -z "${WIN_PACKAGE_SERVER}" ]; then
593 610  
594   - scp "${FILENAME}" ${WIN_PACKAGE_SERVER}/${TARGET_PATH}
  611 + scp "${FILENAME}" "${WIN_PACKAGE_SERVER}/${TARGET_PATH}/$(basename ${FILENAME})"
595 612 if [ "$?" != "0" ]; then
596   - failed "Can't publish ${1} to ${WIN_PACKAGE_SERVER}/${TARGET_PATH}"
  613 + failed "Can't publish ${WIN_PACKAGE_SERVER}/${TARGET_PATH}/$(basename ${FILENAME})"
  614 + else
  615 + echo "Published to ${WIN_PACKAGE_SERVER}/${TARGET_PATH}/$(basename ${FILENAME})"
597 616 fi
598 617  
599 618 fi
... ... @@ -768,13 +787,21 @@ do
768 787 ;;
769 788  
770 789 CLEAR)
771   - if [ -d ~/public_html/win/${PRODUCT_NAME} ]; then
772   - rm -fr ~/public_html/win/${PRODUCT_NAME}/{x86_32,x86_64}
773   - fi
  790 + CLEAR_TARGET_PATH=1
774 791  
775   - if [ ! -z "${XDG_PUBLICSHARE_DIR}" ] && [ -d "${XDG_PUBLICSHARE_DIR}/${PRODUCT_NAME}" ]; then
776   - rm -fr ${XDG_PUBLICSHARE_DIR}/${PRODUCT_NAME}/{x86_32,x86_64}
777   - fi
  792 +# if [ ${BUILD_UNSTABLE} == "1" ]; then
  793 +# CLEAR_TARGET="${PRODUCT_NAME}/unstable"
  794 +# else
  795 +# CLEAR_TARGET="${PRODUCT_NAME}/stable"
  796 +# fi
  797 +#
  798 +# if [ -d ~/public_html/win/${STORAGE_PATH} ]; then
  799 +# echo rm -fr ~/public_html/win/${CLEAR_TARGET}/{x86_32,x86_64}
  800 +# fi
  801 +#
  802 +# if [ ! -z "${XDG_PUBLICSHARE_DIR}" ] && [ -d "${XDG_PUBLICSHARE_DIR}/${CLEAR_TARGET}" ]; then
  803 +# echo rm -fr ${XDG_PUBLICSHARE_DIR}/${CLEAR_TARGET}/{x86_32,x86_64}
  804 +# fi
778 805  
779 806 ;;
780 807  
... ... @@ -783,7 +810,7 @@ do
783 810 ;;
784 811  
785 812 TARGET-ARCHS)
786   - TARGET_ARCHS=${value}
  813 + TARGET_ARCHS=$(echo ${value} | sed "s@,@ @g")
787 814 ;;
788 815  
789 816 NO-PRE-REQS)
... ... @@ -855,9 +882,7 @@ do
855 882  
856 883 fi
857 884  
858   - if [ -d ~/public_html/win/${PRODUCT_NAME} ]; then
859   - echo " --clear Replace the contents of public folders"
860   - fi
  885 + echo " --clear Replace the contents of public folders"
861 886  
862 887 echo ""
863 888 exit 0
... ...
win/pw3270.nsi.in
... ... @@ -133,10 +133,15 @@ SubSection &quot;@PRODUCT_NAME@&quot; SecMain
133 133  
134 134 # Locale files
135 135 CreateDirectory "$INSTDIR\locale\pt_BR\LC_MESSAGES"
136   - file "/oname=$INSTDIR\locale\pt_BR\LC_MESSAGES\@PACKAGE@.mo" "share\locale\pt_BR\LC_MESSAGES\@PACKAGE@.mo"
  136 + file "/oname=$INSTDIR\locale\pt_BR\LC_MESSAGES\@PACKAGE_NAME@.mo" "share\locale\pt_BR\LC_MESSAGES\@PACKAGE_NAME@.mo"
137 137 file "/oname=$INSTDIR\locale\pt_BR\LC_MESSAGES\lib@LIBRARY_NAME@.mo" "share\locale\pt_BR\LC_MESSAGES\lib@LIBRARY_NAME@.mo"
138 138 file "/oname=$INSTDIR\locale\pt_BR\LC_MESSAGES\libv3270.mo" "share\locale\pt_BR\LC_MESSAGES\libv3270.mo"
139 139  
  140 + # Customized icons
  141 + CreateDirectory "$INSTDIR\icons"
  142 + file "/oname=$INSTDIR\icons\gtk-connect-symbolic.svg" "share\@PRODUCT_NAME@\icons\gtk-connect-symbolic.svg"
  143 + file "/oname=$INSTDIR\icons\gtk-disconnect-symbolic.svg" "share\@PRODUCT_NAME@\icons\gtk-disconnect-symbolic.svg"
  144 +
140 145 # define uninstaller name
141 146 SetRegView 32
142 147  
... ...