1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 #include "qg_dlgmtext.h"
27
28 #include <QTextCodec>
29 #include <QTextStream>
30 #include <QFileDialog>
31 #include "rs_system.h"
32 #include "rs_settings.h"
33 #include "rs_font.h"
34 #include "rs_graphic.h"
35 #include "rs_math.h"
36
37 /*
38 * Constructs a QG_DlgMText as a child of 'parent', with the
39 * name 'name' and widget flags set to 'f'.
40 *
41 * The dialog will by default be modeless, unless you set 'modal' to
42 * true to construct a modal dialog.
43 */
QG_DlgMText(QWidget * parent,bool modal,Qt::WindowFlags fl)44 QG_DlgMText::QG_DlgMText(QWidget* parent, bool modal, Qt::WindowFlags fl)
45 : QDialog(parent, fl), saveSettings(true)
46 {
47 setModal(modal);
48 setupUi(this);
49
50 init();
51 }
52
53 /*
54 * Destroys the object and frees any allocated resources
55 */
~QG_DlgMText()56 QG_DlgMText::~QG_DlgMText()
57 {
58 destroy();
59 // no need to delete child widgets, Qt does it all for us
60 }
61
62 /*
63 * Sets the strings of the subwidgets using the current
64 * language.
65 */
languageChange()66 void QG_DlgMText::languageChange()
67 {
68 retranslateUi(this);
69 }
70
init()71 void QG_DlgMText::init() {
72 cbFont->init();
73 font=NULL;
74 text = NULL;
75 isNew = false;
76 updateUniCharComboBox(0);
77 updateUniCharButton(0);
78 }
79
80
updateUniCharComboBox(int)81 void QG_DlgMText::updateUniCharComboBox(int) {
82 QString t = cbUniPage->currentText();
83 int i1 = t.indexOf('-');
84 int i2 = t.indexOf(']');
85 int min = t.mid(1, i1-1).toInt(NULL, 16);
86 int max = t.mid(i1+1, i2-i1-1).toInt(NULL, 16);
87
88 cbUniChar->clear();
89 for (int c=min; c<=max; c++) {
90 char buf[5];
91 snprintf(buf,5, "%04X", c);
92 cbUniChar->addItem(QString("[%1] %2").arg(buf).arg(QChar(c)));
93 }
94 }
95
96 //set saveText to false, so, settings won't be saved during destroy, feature request#3445306
reject()97 void QG_DlgMText::reject() {
98 saveSettings=false;
99 QDialog::reject();
100 }
101
destroy()102 void QG_DlgMText::destroy() {
103 if (isNew&&saveSettings) {
104 RS_SETTINGS->beginGroup("/Draw");
105 RS_SETTINGS->writeEntry("/TextHeight", leHeight->text());
106 RS_SETTINGS->writeEntry("/TextFont", cbFont->currentText());
107 RS_SETTINGS->writeEntry("/TextDefault", (int)cbDefault->isChecked());
108 RS_SETTINGS->writeEntry("/TextAlignment", getAlignment());
109 //RS_SETTINGS->writeEntry("/TextLetterSpacing", leLetterSpacing->text());
110 //RS_SETTINGS->writeEntry("/TextWordSpacing", leWordSpacing->text());
111 RS_SETTINGS->writeEntry("/TextLineSpacingFactor",
112 leLineSpacingFactor->text());
113 RS_SETTINGS->writeEntry("/TextString", teText->toPlainText());
114 //RS_SETTINGS->writeEntry("/TextShape", getShape());
115 RS_SETTINGS->writeEntry("/TextAngle", leAngle->text());
116 //RS_SETTINGS->writeEntry("/TextRadius", leRadius->text());
117 RS_SETTINGS->endGroup();
118 }
119 }
120
121
122 /**
123 * Sets the text entity represented by this dialog.
124 */
setText(RS_MText & t,bool isNew)125 void QG_DlgMText::setText(RS_MText& t, bool isNew) {
126 text = &t;
127 this->isNew = isNew;
128
129 QString fon;
130 QString height;
131 QString def;
132 QString alignment;
133 //QString letterSpacing;
134 //QString wordSpacing;
135 QString lineSpacingFactor;
136 QString str;
137 //QString shape;
138 QString angle;
139
140 if (isNew) {
141 wPen->hide();
142 lLayer->hide();
143 cbLayer->hide();
144 RS_SETTINGS->beginGroup("/Draw");
145 //default font depending on locale
146 //default font depending on locale (RLZ-> check this: QLocale::system().name() returns "fr_FR")
147 QByteArray iso = RS_System::localeToISO( QLocale::system().name().toLocal8Bit() );
148 // QByteArray iso = RS_System::localeToISO( QTextCodec::locale() );
149 if (iso=="ISO8859-1") {
150 fon = RS_SETTINGS->readEntry("/TextFont", "normallatin1");
151 } else if (iso=="ISO8859-2") {
152 fon = RS_SETTINGS->readEntry("/TextFont", "normallatin2");
153 } else if (iso=="ISO8859-7") {
154 fon = RS_SETTINGS->readEntry("/TextFont", "greekc");
155 } else if (iso=="KOI8-U" || iso=="KOI8-R") {
156 fon = RS_SETTINGS->readEntry("/TextFont", "cyrillic_ii");
157 } else {
158 fon = RS_SETTINGS->readEntry("/TextFont", "standard");
159 }
160 height = RS_SETTINGS->readEntry("/TextHeight", "1.0");
161 def = RS_SETTINGS->readEntry("/TextDefault", "1");
162 alignment = RS_SETTINGS->readEntry("/TextAlignment", "1");
163 //letterSpacing = RS_SETTINGS->readEntry("/TextLetterSpacing", "0");
164 //wordSpacing = RS_SETTINGS->readEntry("/TextWordSpacing", "0");
165 lineSpacingFactor = RS_SETTINGS->readEntry("/TextLineSpacingFactor", "1");
166 str = RS_SETTINGS->readEntry("/TextString", "");
167 //shape = RS_SETTINGS->readEntry("/TextShape", "0");
168 angle = RS_SETTINGS->readEntry("/TextAngle", "0");
169 //radius = RS_SETTINGS->readEntry("/TextRadius", "10");
170 RS_SETTINGS->endGroup();
171 } else {
172 fon = text->getStyle();
173 setFont(fon);
174 height = QString("%1").arg(text->getHeight());
175 if (font) {
176 if (font->getLineSpacingFactor()==text->getLineSpacingFactor()) {
177 def = "1";
178 } else {
179 def = "0";
180 }
181 }
182 alignment = QString("%1").arg(text->getAlignment());
183 //QString letterSpacing = RS_SETTINGS->readEntry("/TextLetterSpacing", "0");
184 //QString wordSpacing = RS_SETTINGS->readEntry("/TextWordSpacing", "0");
185 lineSpacingFactor = QString("%1").arg(text->getLineSpacingFactor());
186
187 /* // Doesn't make sense. We don't want to show native DXF strings in the Dialog.
188 #if defined(OOPL_VERSION) && defined(Q_WS_WIN)
189 QCString iso = RS_System::localeToISO( QTextCodec::locale() );
190 QTextCodec *codec = QTextCodec::codecForName(iso);
191 if (codec) {
192 str = codec->toUnicode(RS_FilterDXF::toNativeString(text->getText().local8Bit()));
193 } else {
194 str = RS_FilterDXF::toNativeString(text->getText().local8Bit());
195 }
196 #else*/
197 str = text->getText();
198 //#endif
199 //QString shape = RS_SETTINGS->readEntry("/TextShape", "0");
200 angle = QString("%1").arg(RS_Math::rad2deg(text->getAngle()));
201 wPen->setPen(text->getPen(false), true, false, "Pen");
202 RS_Graphic* graphic = text->getGraphic();
203 if (graphic) {
204 cbLayer->init(*(graphic->getLayerList()), false, false);
205 }
206 RS_Layer* lay = text->getLayer(false);
207 if (lay) {
208 cbLayer->setLayer(*lay);
209 }
210 }
211
212 cbDefault->setChecked(def=="1");
213 setFont(fon);
214 leHeight->setText(height);
215 setAlignment(alignment.toInt());
216 if (def!="1" || font==NULL) {
217 //leLetterSpacing->setText(letterSpacing);
218 //leWordSpacing->setText(wordSpacing);
219 leLineSpacingFactor->setText(lineSpacingFactor);
220 } else {
221 //leLetterSpacing->setText(font->getLetterSpacing());
222 //leWordSpacing->setText(font->getWordSpacing());
223 leLineSpacingFactor->setText(
224 QString("%1").arg(font->getLineSpacingFactor()));
225 }
226 teText->setText(str);
227 //setShape(shape.toInt());
228 leAngle->setText(angle);
229 //leRadius->setText(radius);
230 teText->setFocus();
231 teText->selectAll();
232 }
233
234
235 /**
236 * Updates the text entity represented by the dialog to fit the choices of the user.
237 */
updateText()238 void QG_DlgMText::updateText() {
239 if (text) {
240 text->setStyle(cbFont->currentText());
241 text->setHeight(leHeight->text().toDouble());
242
243 //fix for windows (causes troubles if locale returns en_us):
244 /*#if defined(OOPL_VERSION) && defined(Q_WS_WIN)
245 QCString iso = RS_System::localeToISO( QTextCodec::locale() );
246 text->setText(
247 RS_FilterDXF::toNativeString(
248 QString::fromLocal8Bit( QTextCodec::codecForName( iso )->fromUnicode( teText->text() ) )
249 )
250 );
251 #else*/
252 text->setText(teText->toPlainText());
253 //#endif
254 //text->setLetterSpacing(leLetterSpacing.toDouble());
255 text->setLineSpacingFactor(leLineSpacingFactor->text().toDouble());
256 text->setAlignment(getAlignment());
257 text->setAngle(RS_Math::deg2rad(leAngle->text().toDouble()));
258 }
259 if (text && !isNew) {
260 text->setPen(wPen->getPen());
261 text->setLayer(cbLayer->currentText());
262 text->update();
263 }
264 }
265
266
setAlignmentTL()267 void QG_DlgMText::setAlignmentTL() {
268 setAlignment(1);
269 }
270
setAlignmentTC()271 void QG_DlgMText::setAlignmentTC() {
272 setAlignment(2);
273 }
274
setAlignmentTR()275 void QG_DlgMText::setAlignmentTR() {
276 setAlignment(3);
277 }
278
setAlignmentML()279 void QG_DlgMText::setAlignmentML() {
280 setAlignment(4);
281 }
282
setAlignmentMC()283 void QG_DlgMText::setAlignmentMC() {
284 setAlignment(5);
285 }
286
setAlignmentMR()287 void QG_DlgMText::setAlignmentMR() {
288 setAlignment(6);
289 }
290
setAlignmentBL()291 void QG_DlgMText::setAlignmentBL() {
292 setAlignment(7);
293 }
294
setAlignmentBC()295 void QG_DlgMText::setAlignmentBC() {
296 setAlignment(8);
297 }
298
setAlignmentBR()299 void QG_DlgMText::setAlignmentBR() {
300 setAlignment(9);
301 }
302
setAlignment(int a)303 void QG_DlgMText::setAlignment(int a) {
304 bTL->setChecked(false);
305 bTC->setChecked(false);
306 bTR->setChecked(false);
307 bML->setChecked(false);
308 bMC->setChecked(false);
309 bMR->setChecked(false);
310 bBL->setChecked(false);
311 bBC->setChecked(false);
312 bBR->setChecked(false);
313
314 switch (a) {
315 case 1:
316 bTL->setChecked(true);
317 break;
318 case 2:
319 bTC->setChecked(true);
320 break;
321 case 3:
322 bTR->setChecked(true);
323 break;
324 case 4:
325 bML->setChecked(true);
326 break;
327 case 5:
328 bMC->setChecked(true);
329 break;
330 case 6:
331 bMR->setChecked(true);
332 break;
333 case 7:
334 bBL->setChecked(true);
335 break;
336 case 8:
337 bBC->setChecked(true);
338 break;
339 case 9:
340 bBR->setChecked(true);
341 break;
342 default:
343 break;
344 }
345 }
346
getAlignment()347 int QG_DlgMText::getAlignment() {
348 if (bTL->isChecked()) {
349 return 1;
350 } else if (bTC->isChecked()) {
351 return 2;
352 } else if (bTR->isChecked()) {
353 return 3;
354 } else if (bML->isChecked()) {
355 return 4;
356 } else if (bMC->isChecked()) {
357 return 5;
358 } else if (bMR->isChecked()) {
359 return 6;
360 } else if (bBL->isChecked()) {
361 return 7;
362 } else if (bBC->isChecked()) {
363 return 8;
364 } else if (bBR->isChecked()) {
365 return 9;
366 }
367
368 return 1;
369 }
370
setFont(const QString & f)371 void QG_DlgMText::setFont(const QString& f) {
372 cbFont->setCurrentIndex( cbFont->findText(f) );
373 font = cbFont->getFont();
374 defaultChanged(false);
375 }
376
377 /*
378 void QG_DlgText::setShape(int s) {
379 switch (s) {
380 case 0:
381 rbStraight->setChecked(true);
382 break;
383 case 1:
384 rbRound1->setChecked(true);
385 break;
386 case 2:
387 rbRound2->setChecked(true);
388 break;
389 default:
390 break;
391 }
392 }
393
394 int QG_DlgText::getShape() {
395 if (rbStraight->isOn()) {
396 return 0;
397 } else if (rbRound1->isOn()) {
398 return 1;
399 } else if (rbRound2->isOn()) {
400 return 2;
401 }
402 return 1;
403 }
404 */
405
defaultChanged(bool)406 void QG_DlgMText::defaultChanged(bool) {
407 if (cbDefault->isChecked() && font) {
408 leLineSpacingFactor->setText(
409 QString("%1").arg(font->getLineSpacingFactor()));
410 }
411 }
412
loadText()413 void QG_DlgMText::loadText() {
414 QString fn = QFileDialog::getOpenFileName( this, QString(), QString());
415 if (!fn.isEmpty()) {
416 load(fn);
417 }
418 }
419
load(const QString & fn)420 void QG_DlgMText::load(const QString& fn) {
421 QFile f(fn);
422 if (!f.open(QIODevice::ReadOnly)) {
423 return;
424 }
425
426 QTextStream ts(&f);
427 teText->setText(ts.readAll());
428 }
429
saveText()430 void QG_DlgMText::saveText() {
431 QString fn = QFileDialog::getSaveFileName(this, QString(), QString());
432 if (!fn.isEmpty()) {
433 save(fn);
434 }
435 }
436
save(const QString & fn)437 void QG_DlgMText::save(const QString& fn) {
438 QString text = teText->toPlainText();
439 QFile f(fn);
440 if (f.open(QIODevice::WriteOnly)) {
441 QTextStream t(&f);
442 t << text;
443 f.close();
444 }
445 }
446
insertSymbol(int)447 void QG_DlgMText::insertSymbol(int) {
448 QString str = cbSymbol->currentText();
449 int i=str.indexOf('(');
450 if (i!=-1) {
451 teText->textCursor().insertText(QString("%1").arg(str.at(i+1)));
452 }
453 }
454
updateUniCharButton(int)455 void QG_DlgMText::updateUniCharButton(int) {
456 QString t = cbUniChar->currentText();
457 int i1 = t.indexOf(']');
458 int c = t.mid(1, i1-1).toInt(NULL, 16);
459 bUnicode->setText(QString("%1").arg(QChar(c)));
460 }
461
insertChar()462 void QG_DlgMText::insertChar() {
463 QString t = cbUniChar->currentText();
464 int i1 = t.indexOf(']');
465 int c = t.mid(1, i1-1).toInt(NULL, 16);
466 teText->textCursor().insertText( QString("%1").arg(QChar(c)) );
467 }
468