1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
//
// String File Writer code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include "io/String_Writer.h"
#include "Fluid.h"
#include "Project.h"
#include "nodes/Window_Node.h"
#include "nodes/Function_Node.h"
using namespace fld;
using namespace fld::io;
/**
Write a string to a file, replacing all non-ASCII characters with octal codes.
\param[in] out output file
\param[in] text write this NUL terminated utf-8 string
\return EOF if any of the file access calls failed, 0 if OK
*/
static int write_escaped_strings(FILE *out, const char *text) {
int ret = 0;
const unsigned char *utf8_text = (const unsigned char *)text;
for (const unsigned char *s = utf8_text; *s; ++s) {
unsigned char c = *s;
// escape control characters, delete, all utf-8, and the double quotes
// note: we should have an option in the project settings to allow utf-8
// characters in the output text and not escape them
if (c < 32 || c > 126 || c == '\"') {
if (c == '\r') {
ret = fputs("\\r", out);
} else if (c == '\n') {
ret = fputs("\\n", out);
} else {
ret = fprintf(out, "\\%03o", c);
}
} else {
ret = putc((int)c, out);
}
}
return ret;
}
/**
Write a file that contains all label and tooltip strings for internationalization.
The user is responsible to set the right file name extension. The file format
is determined by `proj_.i18n.type`.
\param[in] filename file path and name to a file that will hold the strings
\return 1 if the file could not be opened for writing, or the result of `fclose`.
*/
int fld::io::write_strings(Project &proj, const std::string &filename) {
Node *p;
Widget_Node *w;
int i;
FILE *fp = fl_fopen(filename.c_str(), "wb");
if (!fp) return 1;
switch (proj.i18n.type) {
case fld::I18n_Type::NONE : /* None, just put static text out */
fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
for (auto w: proj.tree.all_widgets()) {
if (w->label()) {
write_escaped_strings(fp, w->label());
putc('\n', fp);
}
if (!w->tooltip().empty()) {
write_escaped_strings(fp, w->tooltip().c_str());
putc('\n', fp);
}
}
break;
case fld::I18n_Type::GNU : /* GNU gettext, put a .po file out */
fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
for (p = proj.tree.first; p; p = p->next) {
if (p->is_widget()) {
w = (Widget_Node *)p;
if (w->label()) {
fputs("msgid \"", fp);
write_escaped_strings(fp, w->label());
fputs("\"\n", fp);
fputs("msgstr \"", fp);
write_escaped_strings(fp, w->label());
fputs("\"\n", fp);
}
if (!w->tooltip().empty()) {
fputs("msgid \"", fp);
write_escaped_strings(fp, w->tooltip().c_str());
fputs("\"\n", fp);
fputs("msgstr \"", fp);
write_escaped_strings(fp, w->tooltip().c_str());
fputs("\"\n", fp);
}
}
}
break;
case fld::I18n_Type::POSIX : /* POSIX catgets, put a .msg file out */
fprintf(fp, "$ generated by Fast Light User Interface Designer (fluid) version %.4f\n",
FL_VERSION);
fprintf(fp, "$set %s\n", proj.i18n.posix_set.c_str());
fputs("$quote \"\n", fp);
for (i = 1, p = proj.tree.first; p; p = p->next) {
if (p->is_widget()) {
w = (Widget_Node *)p;
if (w->label()) {
fprintf(fp, "%d \"", i ++);
write_escaped_strings(fp, w->label());
fputs("\"\n", fp);
}
if (!w->tooltip().empty()) {
fprintf(fp, "%d \"", i ++);
write_escaped_strings(fp, w->tooltip().c_str());
fputs("\"\n", fp);
}
}
}
break;
}
return fclose(fp);
}
|