Salome HOME
6a08e3e864a4ab3bc44110a97a7545f36c647643
[modules/gui.git] / src / Qtx / QtxFontEdit.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File:      QtxFontEdit.cxx
21 // Author:    Sergey TELKOV
22 //
23 #include "QtxFontEdit.h"
24
25 #include "QtxComboBox.h"
26
27 #include <QLayout>
28 #include <QToolButton>
29 #include <QFontDialog>
30 #include <QFontDatabase>
31 #include <QFontComboBox>
32
33 /*!
34   \class QtxFontEdit
35   \brief The QtxFontEdit class represents a widget for font
36   preference items editing.
37
38   The font preference item is represented as the drop-down combo box 
39   filled with the list of available fonts. Additional controls for
40   modifying font properties ('bold', 'italic', font size, etc) are also
41   available for use.
42
43   Initial font value can be set with setCurrentFont() method. Chosen font
44   can be retrieved with the currentFont() method.
45
46   Font properties can be set with the setFontSize(), setFontFamily(), 
47   setFontScripting() methods and retrieved with fontSize(), fontFamily(), 
48   fontScripting() methods.
49
50   Additional widgets for direct modyfing font properties are available
51   with use of setFeatures() method.
52 */
53
54 /*!
55   \brief Constructor
56   \param feat font widget features (ORed QtxFontEdit::Features flags)
57   \param parent parent widget
58 */
59 QtxFontEdit::QtxFontEdit( const int feat, QWidget* parent )
60 : QFrame( parent ),
61   myFeatures( feat ),
62   myMode( Native )
63 {
64   initialize();
65 }
66
67 /*!
68   \brief Constructor
69   \param parent parent widget
70
71   All font widget features are enabled.
72 */
73 QtxFontEdit::QtxFontEdit( QWidget* parent )
74 : QFrame( parent ),
75   myFeatures( All ),
76   myMode( Native )
77 {
78   initialize();
79 }
80
81 /*!
82   \brief Destructor
83 */
84 QtxFontEdit::~QtxFontEdit()
85 {
86 }
87
88 /*!
89   \brief Get font widget features.
90   \return font widget features (ORed QtxFontEdit::Features flags)
91   \sa setFeatures()
92 */
93 int QtxFontEdit::features() const
94 {
95   return myFeatures;
96 }
97
98 /*!
99   \brief Set font widget features.
100   \param f font widget features (ORed QtxFontEdit::Features flags)
101   \sa features()
102 */
103 void QtxFontEdit::setFeatures( const int f )
104 {
105   if ( myFeatures == f )
106     return;
107
108   myFeatures = f;
109   updateState();
110 }
111
112 /*!
113   \brief Get currently selected font.
114   \return current font
115   \sa setCurrentFont()
116 */
117 QFont QtxFontEdit::currentFont() const
118 {
119   QFont fnt( fontFamily(), fontSize() );
120
121   int script = fontScripting();
122   fnt.setBold( script & Bold );
123   fnt.setItalic( script & Italic );
124   fnt.setUnderline( script & Underline );
125   fnt.setOverline( script & Shadow ); //addVtkFontPref( tr( "LABELS" ), valLblFontGr, "values_labeling_font" );
126
127   return fnt;
128 }
129
130 /*!
131   \brief Set currently selected font.
132   \param fnt current font
133   \sa currentFont()
134 */
135 void QtxFontEdit::setCurrentFont( const QFont& fnt )
136 {
137   // VSR 25/08/2016: IPAL53224
138   // blocking signals of QFontComboBox breaks its internal business logic
139   // that prevents correct retrieving of available sizes for the font in case
140   // when some non-existent font is replaced by its closest analogue
141   //myFamily->blockSignals( true );
142   myCustomFams->blockSignals( true );
143   mySize->blockSignals( true );
144   myB->blockSignals( true );
145   myI->blockSignals( true );
146   myU->blockSignals( true );
147   
148   setFontFamily( fnt.family() );
149   setFontSize( fnt.pointSize() );
150   setFontScripting( ( fnt.bold() ? Bold : 0 ) |
151                     ( fnt.italic() ? Italic : 0 ) |
152                     ( fnt.underline() ? Underline : 0 ) | 
153                     ( fnt.overline() ? Shadow : 0 ) );
154
155   //myFamily->blockSignals( false );
156   myCustomFams->blockSignals( false );
157   mySize->blockSignals( false );
158   myB->blockSignals( false );
159   myI->blockSignals( false );
160   myU->blockSignals( false );
161
162   emit( changed( currentFont() ) );
163 }
164
165 /*!
166   \brief Get selected font family name.
167   \return current font family name
168   \sa setFontFamily()
169 */
170 QString QtxFontEdit::fontFamily() const
171 {
172   if ( myMode == Native )
173     return myFamily->currentFont().family();
174   else
175     return myCustomFams->currentText();
176 }
177
178 /*!
179   \brief Get selected font size.
180   \return current font size
181   \sa setFontSize()
182 */
183 int QtxFontEdit::fontSize() const
184 {
185   bool ok;
186   int pSize = mySize->currentText().toInt( &ok );
187   return ok ? pSize : 0;
188 }
189
190 /*!
191   \brief Get selected font scripting.
192   \return current font scripting
193   \sa setFontScripting()
194 */
195 int QtxFontEdit::fontScripting() const
196 {
197   return ( myB->isChecked() ? Bold : 0 ) |
198          ( myI->isChecked() ? Italic : 0 ) |
199          ( myU->isChecked() ? Underline : 0 ) |
200          ( myS->isChecked() ? Shadow : 0 ) ;
201 }
202
203 /*!
204   \brief Set font family name.
205   \param fam new font family name
206   \sa fontFamily()
207 */
208 void QtxFontEdit::setFontFamily( const QString& fam )
209 {
210   if ( myMode == Native )
211   {
212     myFamily->setCurrentFont( QFont( fam ) );
213     onFontChanged( myFamily->currentFont() );  
214   }
215   else 
216   {
217     myCustomFams->setCurrentIndex( myCustomFams->findText( fam ) );
218     if ( !myCustomFams->signalsBlocked() )
219       emit( changed( currentFont() ) );
220   }
221 }
222
223 /*!
224   \brief Set font size.
225   \param fam new font size
226   \sa fontSize()
227 */
228 void QtxFontEdit::setFontSize( const int s )
229 {
230   if ( s <= 0 )
231     return;
232
233   int idx = mySize->findText( QString::number( s ) );
234   if ( idx != -1 )
235     mySize->setCurrentIndex( idx );
236   else if ( mySize->isEditable() )
237     mySize->setEditText( QString::number( s ) );
238 }
239
240 /*!
241   \brief Set font scripting.
242   \param fam new font scripting
243   \sa fontScripting()
244 */
245 void QtxFontEdit::setFontScripting( const int script )
246 {
247   myB->setChecked( script & Bold );
248   myI->setChecked( script & Italic );
249   myU->setChecked( script & Underline );
250   myS->setChecked( script & Shadow );
251 }
252
253 /*!
254   \brief Update widget state
255 */
256 void QtxFontEdit::updateState()
257 {
258   int feat = features();
259
260   myFamily->setVisible( ( feat & Family ) && myMode == Native );
261   myCustomFams->setVisible( ( feat & Family ) && myMode == Custom );
262   mySize->setVisible( feat & Size );
263   myB->setVisible( feat & Bold );
264   myI->setVisible( feat & Italic );
265   myU->setVisible( feat & Underline );
266   myS->setVisible( feat & Shadow );
267   myPreview->setVisible( feat & Preview );
268
269   mySize->setEditable( feat & UserSize );
270 }
271
272 /*!
273   \brief Called when current font is changed.
274   \param f (not used)
275 */
276 void QtxFontEdit::onFontChanged( const QFont& /*f*/ )
277 {
278   bool blocked = mySize->signalsBlocked();
279   mySize->blockSignals( true );
280
281   int s = fontSize();
282   mySize->clear();
283
284   QList<int> szList = QFontDatabase().pointSizes( fontFamily() );
285   QStringList sizes;
286   for ( QList<int>::const_iterator it = szList.begin(); it != szList.end(); ++it )
287     sizes.append( QString::number( *it ) );
288   mySize->addItems( sizes );
289
290   setFontSize( s );
291
292   mySize->blockSignals( blocked );
293
294   if ( !myFamily->signalsBlocked() )
295     emit( changed( currentFont() ) );
296 }
297
298 void QtxFontEdit::onPropertyChanged()
299 {
300   emit( changed( currentFont() ) );
301 }
302
303 /*!
304   \brief Called when "Preview" button is clicked.
305   \param on (not used)
306 */
307 void QtxFontEdit::onPreview( bool /*on*/ )
308 {
309   bool ok;
310   QFont fnt = QFontDialog::getFont( &ok, currentFont() );
311
312   if ( ok )
313     setCurrentFont( fnt );
314 }
315
316 /*
317   \brief Perform internal intialization.
318 */
319 void QtxFontEdit::initialize()
320 {
321   QHBoxLayout* base = new QHBoxLayout( this );
322   base->setMargin( 0 );
323   base->setSpacing( 5 );
324
325   base->addWidget( myFamily = new QFontComboBox( this ) );
326   base->addWidget( myCustomFams = new QComboBox( this ) );
327   base->addWidget( mySize = new QtxComboBox( this ) );
328   mySize->setInsertPolicy( QComboBox::NoInsert );
329   mySize->setValidator( new QIntValidator( 1, 250, mySize ) );
330
331   base->addWidget( myB = new QToolButton( this ) );
332   myB->setText( tr( "B" ) );
333   myB->setCheckable( true );
334
335   base->addWidget( myI = new QToolButton( this ) );
336   myI->setText( tr( "I" ) );
337   myI->setCheckable( true );
338
339   base->addWidget( myU = new QToolButton( this ) );
340   myU->setText( tr( "U" ) );
341   myU->setCheckable( true );
342
343   base->addWidget( myS = new QToolButton( this ) );
344   myS->setText( tr( "S" ) );
345   myS->setCheckable( true );
346
347   base->addWidget( myPreview = new QToolButton( this ) );
348   myPreview->setText( "..." );
349
350   myFamily->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
351   myCustomFams->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
352
353   connect( myPreview, SIGNAL( clicked( bool ) ),                    this, SLOT( onPreview( bool ) ) );
354   connect( myFamily,  SIGNAL( currentFontChanged( const QFont& ) ), this, SLOT( onFontChanged( const QFont& ) ) );
355   connect( mySize,    SIGNAL( currentIndexChanged( int ) ),         this, SLOT( onPropertyChanged() ) );
356   connect( mySize,    SIGNAL( editTextChanged( QString ) ),         this, SLOT( onPropertyChanged() ) );
357   connect( myB,       SIGNAL( toggled( bool ) ),                    this, SLOT( onPropertyChanged() ) );
358   connect( myI,       SIGNAL( toggled( bool ) ),                    this, SLOT( onPropertyChanged() ) );
359   connect( myU,       SIGNAL( toggled( bool ) ),                    this, SLOT( onPropertyChanged() ) );
360
361   myCustomFams->hide();
362   myS->hide();
363
364   updateState();
365   onFontChanged( currentFont() );
366 }
367
368 /*!
369   \brief Specifies whether widget works in Native or Custom mode. Native mode 
370   is intended for working with system fonts. Custom mode is intended for 
371   working with manually defined set of fonts. Set of custom fonts can be 
372   specified with setCustomFonts() method 
373   \param mode mode from QtxFontEdit::Mode enumeration
374   \sa mode()
375 */
376 void QtxFontEdit::setMode( const int mode )
377 {
378   if ( myMode == mode )
379     return;
380
381   myMode = mode;
382
383   myFamily->setVisible( myMode == Native );
384   myCustomFams->setVisible( myMode == Custom );
385
386   updateGeometry();
387 }
388
389 /*!
390   \brief Verifies whether widget works in Native or Custom mode
391   \return Native or Custom mode
392   \sa setMode()
393 */
394 int QtxFontEdit::mode() const
395 {
396   return myMode;
397 }
398
399 /*!
400   \brief Sets list of custom fonts. 
401   <b>This method is intended for working in Custom mode.</b>
402   \param fams list of families
403   \sa fonts(), setMode()
404 */
405 void QtxFontEdit::setFonts( const QStringList& fams )
406 {
407   QString currFam = myCustomFams->currentText();
408   
409   myCustomFams->clear();
410   myCustomFams->addItems( fams );
411
412   int ind = myCustomFams->findText( currFam );
413   if ( ind != -1 )
414     myCustomFams->setCurrentIndex( ind );
415
416   setSizes( QList<int>() );
417 }
418
419 /*!
420   \brief Sets list of available font sizes. 
421   <b>This method is intended for working in Custom mode.</b> The list of sizes can 
422   be empty. In this case system generate listof size automatically from 8 till 72.
423   \param sizes list of sizes
424   \sa sizes(), setMode()
425 */
426 void QtxFontEdit::setSizes( const QList<int>& sizes )
427 {
428   QString currSize = mySize->currentText();
429
430   mySize->clear();
431   if ( !sizes.isEmpty() )
432   {
433     QStringList szList;
434     for ( QList<int>::const_iterator it = sizes.begin(); it != sizes.end(); ++it )
435       szList.append( QString::number( *it ) );
436     mySize->addItems( szList );
437   }
438   else
439   {
440     static QStringList defLst;
441     if ( defLst.isEmpty() )
442     {
443       QString str( "8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72" );
444       defLst = str.split( " " );
445     }
446     mySize->addItems( defLst );
447   }
448   
449   int ind = mySize->findText( currSize );
450   if ( ind != -1 )
451     mySize->setCurrentIndex( ind );
452 }
453
454 /*!
455   \brief Gets list of custom fonts 
456   \return list of families
457   \sa setFonts(), setMode()
458 */
459 QStringList QtxFontEdit::fonts() const
460 {
461   QStringList fams;
462   for ( int i = 0, n = myCustomFams->count(); i < n; i++ )
463     fams.append( myCustomFams->itemText( i ) );
464   return fams;
465 }
466
467 /*!
468   \brief Gets list of custom fonts 
469   \return list of families
470   \sa setCustomFonts(), setMode()
471 */
472 QList<int> QtxFontEdit::sizes() const
473 {
474   QList<int> lst;
475   for ( int i = 0, n = mySize->count(); i < n; i++ )
476     lst.append( mySize->itemText( i ).toInt() );
477   return lst;
478 }
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498