OpenClonk
C4ConsoleQtLocalizeOverview.cpp
Go to the documentation of this file.
1 /*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5 * Copyright (c) 2013, The OpenClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16 
17 /* String localization editors */
18 
19 #include "C4Include.h"
20 #include "script/C4Value.h"
21 #include "config/C4Config.h"
23 #include "c4group/C4Language.h"
24 
25 
26 /* Single string editor */
27 
28 C4ConsoleQtLocalizeOverviewDlg::C4ConsoleQtLocalizeOverviewDlg(class QMainWindow *parent_window)
29  : QDialog(parent_window, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
30 {
31  ui.setupUi(this);
32  // Size
33  adjustSize();
34  setMinimumSize(size());
35 }
36 
37 int32_t C4ConsoleQtLocalizeOverviewDlg::GetColumnByLanguage(const char *lang) const
38 {
39  // Language column by ID
40  auto iter = lang2col.find(QString(lang));
41  if (iter != lang2col.end())
42  {
43  return iter->second;
44  }
45  // No column matches
46  return -1;
47 }
48 
49 int32_t C4ConsoleQtLocalizeOverviewDlg::AddLanguageColumn(const char *lang_id, const char *lang_name)
50 {
51  // Add column
52  int32_t col = ui.translationTable->columnCount();
53  ui.translationTable->setColumnCount(col + 1);
54  ui.translationTable->horizontalHeader()->setSectionResizeMode(col, QHeaderView::Stretch);
55  // Set header
56  QString text(lang_id);
57  if (lang_name)
58  {
59  text.append(" - ").append(lang_name);
60  }
61  SetTableItem(0, col, TIT_Header, text);
62  // Remember language to resolve index
63  lang2col[QString(lang_id)] = col;
64  col2lang.emplace_back(QString(lang_id));
65  return col;
66 }
67 
68 void C4ConsoleQtLocalizeOverviewDlg::SetTableItem(int32_t row, int32_t col, TableItemType item_type, const QString &text)
69 {
70  // Set entry in translation table
71  auto item = new QTableWidgetItem(QString(text));
72  // Headers and info columns cannot be edited
73  if (item_type != TIT_Entry)
74  {
75  item->setFlags(item->flags() & ~(Qt::ItemIsEditable)); // | Qt::ItemIsSelectable
76  }
77  // Set the entry
78  if (item_type == TIT_Header)
79  {
80  ui.translationTable->setHorizontalHeaderItem(col, item);
81  }
82  else
83  {
84  ui.translationTable->setItem(row, col, item);
85  }
86 }
87 
88 void C4ConsoleQtLocalizeOverviewDlg::reject()
89 {
90  // Cleanup on dialogue close to avoid hanging proplists in C4Value
91  ClearTable();
92  QDialog::reject();
93 }
94 
95 void C4ConsoleQtLocalizeOverviewDlg::ClearTable()
96 {
97  ui.translationTable->clearContents();
98  lang_strings.clear();
99  lang2col.clear();
100  col2lang.clear();
101 }
102 
103 void C4ConsoleQtLocalizeOverviewDlg::Refresh()
104 {
105  // Re-fill
106  is_refreshing = true;
107  // This may take a while; show a dialogue
108  QProgressDialog progress(QString(LoadResStr("IDS_CNS_COLLECTINGLOCALIZATIONS")), QString(), 0, 0, this);
109  progress.setCancelButton(nullptr); // Can't cancel
110  progress.setWindowModality(Qt::WindowModal);
111 
112  // Clear previous
113  ClearTable();
114 
115  // Collect localizable strings
116  C4PropertyCollection lang_string_collector;
117  lang_string_collector.CollectPropLists(P_Function, C4VString(&::Strings.P[P_Translate]));
118  lang_strings = lang_string_collector.GetEntries();
119 
120  // Set up headers
121  ui.translationTable->setRowCount(lang_strings.size());
122  ui.translationTable->setColumnCount(2);
123  SetTableItem(0, 0, TIT_Header, QString(LoadResStr("IDS_CNS_OBJECT")));
124  SetTableItem(0, 1, TIT_Header, QString(LoadResStr("IDS_CNS_PATH")));
125  ui.translationTable->setColumnWidth(0, 100);
126  ui.translationTable->setColumnWidth(1, 200);
127  col2lang.resize(2);
128 
129  // Add default language columns
130  int32_t lang_index = 0;
131  C4LanguageInfo *lang_info;
132  while (lang_info = ::Languages.GetInfo(lang_index++))
133  {
134  AddLanguageColumn(lang_info->Code, lang_info->Name);
135  }
136 
137  // Add them to the table
138  int32_t row = 0;
139  for (auto &entry : lang_strings)
140  {
141  assert(entry.value.GetType() == C4V_PropList);
142  C4PropList *translations_proplist = entry.value._getPropList();
143  assert(translations_proplist);
144 
145  // Add name and path
146  SetTableItem(row, 0, TIT_Info, QString(entry.name.getData()));
147  SetTableItem(row, 1, TIT_Info, QString(entry.path.GetGetPath()));
148 
149  // Add each language
150  for (C4String *lang_str : translations_proplist->GetSortedLocalProperties(false))
151  {
152  if (lang_str->GetData().getLength() == 2)
153  {
154  C4Value text_val;
155  if (translations_proplist->GetPropertyByS(lang_str, &text_val))
156  {
157  C4String *text = text_val.getStr();
158  if (text)
159  {
160  int32_t col = GetColumnByLanguage(lang_str->GetCStr());
161  if (col < 0)
162  {
163  // This is a non-default language. Add a column.
164  col = AddLanguageColumn(lang_str->GetCStr(), nullptr);
165  }
166  // Set text for this translation
167  SetTableItem(row, col, TIT_Entry, QString(text->GetCStr()));
168  }
169  }
170  }
171  }
172  ++row;
173  }
174 
175  // Done!
176  progress.close();
177  is_refreshing = false;
178 }
179 
180 void C4ConsoleQtLocalizeOverviewDlg::OnTableItemChanged(QTableWidgetItem *item)
181 {
182  // User edits only
183  if (is_refreshing)
184  {
185  return;
186  }
187  // Find path to proplist to edit
188  const C4PropertyPath &prop_path = lang_strings[item->row()].path;
189  // Find language to edit
190  QString lang_id = col2lang[item->column()];
191  // Set to new value through control queue
192  QString new_value = item->text();
193  if (new_value.length())
194  {
195  // TODO: Would be better to handle escaping in the C4Value-to-string code
196  new_value = new_value.replace(R"(\)", R"(\\)").replace(R"(")", R"(\")");
197  // Update in script
198  C4PropertyPath set_path(prop_path, lang_id.toUtf8().data());
199  set_path.SetProperty((R"(")" + new_value + R"(")").toUtf8().data());
200  }
201  else
202  {
203  // Empty string: Delete this language entry
204  prop_path.DoCall(FormatString(R""(ResetProperty("%s", %%s))"", lang_id.toUtf8().data()).getData());
205 
206  }
207 }
208 
C4StringTable Strings
Definition: C4Globals.cpp:42
C4Language Languages
Definition: C4Language.cpp:42
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
@ P_Translate
@ P_Function
@ C4V_PropList
Definition: C4Value.h:28
C4Value C4VString(C4String *pStr)
Definition: C4Value.h:243
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
C4LanguageInfo * GetInfo(int iIndex)
Definition: C4Language.cpp:343
char Name[C4MaxLanguageInfo+1]
Definition: C4Language.h:33
char Code[2+1]
Definition: C4Language.h:32
virtual bool GetPropertyByS(const C4String *k, C4Value *pResult) const
Definition: C4PropList.cpp:726
std::vector< C4String * > GetSortedLocalProperties(bool add_prototype=true) const
Definition: C4PropList.cpp:545
const std::vector< Entry > & GetEntries() const
void DoCall(const char *call_string) const
C4String P[P_LAST]
C4String * getStr() const
Definition: C4Value.h:117
const char * getData() const
Definition: StdBuf.h:442