1 //=============================================================================
2 //  MusE Score
3 //  Linux Music Score Editor
4 //
5 //  Copyright (C) 2002-2010 Werner Schweer and others
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //=============================================================================
19 
20 #include "log.h"
21 
22 #include "texttools.h"
23 #include "icons.h"
24 #include "libmscore/text.h"
25 #include "musescore.h"
26 #include "libmscore/score.h"
27 #include "textpalette.h"
28 #include "libmscore/mscore.h"
29 #include "preferences.h"
30 #include "scoreview.h"
31 
32 namespace Ms {
33 
34 TextPalette* textPalette;
35 
36 //---------------------------------------------------------
37 //   textTools
38 //---------------------------------------------------------
39 
textTools()40 TextTools* MuseScore::textTools()
41       {
42       if (!_textTools) {
43             _textTools = new TextTools(this);
44             addDockWidget(Qt::DockWidgetArea(Qt::BottomDockWidgetArea), _textTools);
45             }
46       setFocusPolicy(Qt::NoFocus);
47       return _textTools;
48       }
49 
50 //---------------------------------------------------------
51 //   TextTools
52 //---------------------------------------------------------
53 
TextTools(QWidget * parent)54 TextTools::TextTools(QWidget* parent)
55    : QDockWidget(parent)
56       {
57       setObjectName("text-tools");
58       setAllowedAreas(Qt::DockWidgetAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea));
59       setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
60 
61       text = nullptr;
62       cursor = nullptr;
63 
64       toolbar = new QToolBar(tr("Text Edit"));
65       toolbar->setIconSize(QSize(preferences.getInt(PREF_UI_THEME_ICONWIDTH) * guiScaling,
66                                  preferences.getInt(PREF_UI_THEME_ICONHEIGHT) * guiScaling));
67 
68       showKeyboard = getAction("show-keys");
69       showKeyboard->setCheckable(true);
70       toolbar->addAction(showKeyboard);
71 
72       typefaceBold = toolbar->addAction(*icons[int(Icons::textBold_ICON)], "");
73       typefaceBold->setCheckable(true);
74 
75       typefaceItalic = toolbar->addAction(*icons[int(Icons::textItalic_ICON)], "");
76       typefaceItalic->setCheckable(true);
77 
78       typefaceUnderline = toolbar->addAction(*icons[int(Icons::textUnderline_ICON)], "");
79       typefaceUnderline->setCheckable(true);
80 
81       toolbar->addSeparator();
82 
83       typefaceSubscript = toolbar->addAction(*icons[int(Icons::textSub_ICON)], "");
84       typefaceSubscript->setCheckable(true);
85 
86       typefaceSuperscript = toolbar->addAction(*icons[int(Icons::textSuper_ICON)], "");
87       typefaceSuperscript->setCheckable(true);
88 
89       toolbar->addSeparator();
90 
91       typefaceFamily = new QFontComboBox(this);
92       typefaceFamily->setEditable(false);
93       toolbar->addWidget(typefaceFamily);
94 
95       typefaceSize = new QDoubleSpinBox(this);
96       typefaceSize->setFocusPolicy(Qt::ClickFocus);
97       typefaceSize->setMinimum(1);
98       toolbar->addWidget(typefaceSize);
99 
100       setWidget(toolbar);
101       QWidget* w = new QWidget(this);
102       setTitleBarWidget(w);
103       titleBarWidget()->hide();
104 
105       connect(typefaceSize,        SIGNAL(valueChanged(double)), SLOT(sizeChanged(double)));
106       connect(typefaceFamily,      SIGNAL(currentFontChanged(const QFont&)), SLOT(fontChanged(const QFont&)));
107       connect(typefaceBold,        SIGNAL(triggered(bool)), SLOT(boldClicked(bool)));
108       connect(typefaceItalic,      SIGNAL(triggered(bool)), SLOT(italicClicked(bool)));
109       connect(typefaceUnderline,   SIGNAL(triggered(bool)), SLOT(underlineClicked(bool)));
110       connect(typefaceSubscript,   SIGNAL(triggered(bool)), SLOT(subscriptClicked(bool)));
111       connect(typefaceSuperscript, SIGNAL(triggered(bool)), SLOT(superscriptClicked(bool)));
112       connect(showKeyboard,        SIGNAL(toggled(bool)),   SLOT(showKeyboardClicked(bool)));
113 
114       retranslate();
115       }
116 
117 //---------------------------------------------------------
118 //   retranslate
119 //---------------------------------------------------------
120 
retranslate()121 void TextTools::retranslate()
122       {
123       setWindowTitle(tr("Text Tools"));
124       toolbar->setWindowTitle(tr("Text Edit"));
125       typefaceBold->setToolTip(tr("Bold"));
126       typefaceItalic->setToolTip(tr("Italic"));
127       typefaceSubscript->setToolTip(tr("Subscript"));
128       typefaceSuperscript->setToolTip(tr("Superscript"));
129       }
130 
131 //---------------------------------------------------------
132 //   changeEvent
133 //---------------------------------------------------------
134 
changeEvent(QEvent * event)135 void TextTools::changeEvent(QEvent* event)
136       {
137       QDockWidget::changeEvent(event);
138       if (event->type() == QEvent::LanguageChange)
139             retranslate();
140       }
141 
142 //---------------------------------------------------------
143 //   blockAllSignals
144 //---------------------------------------------------------
145 
blockAllSignals(bool val)146 void TextTools::blockAllSignals(bool val)
147       {
148       typefaceSize->blockSignals(val);
149       typefaceFamily->blockSignals(val);
150       typefaceBold->blockSignals(val);
151       typefaceItalic->blockSignals(val);
152       typefaceUnderline->blockSignals(val);
153       typefaceSubscript->blockSignals(val);
154       typefaceSuperscript->blockSignals(val);
155       typefaceFamily->blockSignals(val);
156       showKeyboard->blockSignals(val);
157       }
158 
159 //---------------------------------------------------------
160 //   updateTools
161 //---------------------------------------------------------
162 
updateTools(EditData & ed)163 void TextTools::updateTools(EditData& ed)
164       {
165       text   = toTextBase(ed.element);
166       IF_ASSERT_FAILED(text) {
167             return;
168             }
169 
170       cursor = text->cursor(ed);
171       IF_ASSERT_FAILED(cursor) {
172             return;
173             }
174 
175       blockAllSignals(true);
176       CharFormat* format = cursor->format();
177 
178       QFont f(format->fontFamily());
179       typefaceFamily->setCurrentFont(f);
180       typefaceFamily->setEnabled(true);
181       typefaceSize->setValue(format->fontSize());
182 
183       typefaceItalic->setChecked(format->italic());
184       typefaceBold->setChecked(format->bold());
185       typefaceUnderline->setChecked(format->underline());
186       typefaceSubscript->setChecked(format->valign() == VerticalAlignment::AlignSubScript);
187       typefaceSuperscript->setChecked(format->valign() == VerticalAlignment::AlignSuperScript);
188 
189       blockAllSignals(false);
190       }
191 
192 //---------------------------------------------------------
193 //   updateText
194 //---------------------------------------------------------
195 
updateText()196 void TextTools::updateText()
197       {
198       if (!text)
199             return;
200       layoutText();
201       }
202 
203 //---------------------------------------------------------
204 //   layoutText
205 //---------------------------------------------------------
206 
layoutText()207 void TextTools::layoutText()
208       {
209       text->triggerLayout();
210       text->score()->update();
211       }
212 
213 //---------------------------------------------------------
214 //   sizeChanged
215 //---------------------------------------------------------
216 
sizeChanged(double value)217 void TextTools::sizeChanged(double value)
218       {
219       IF_ASSERT_FAILED(cursor) {
220             return;
221             }
222       cursor->setFormat(FormatId::FontSize, value);
223       cursor->format()->setFontSize(value);
224       updateText();
225       }
226 
227 //---------------------------------------------------------
228 //   fontChanged
229 //---------------------------------------------------------
230 
fontChanged(const QFont & f)231 void TextTools::fontChanged(const QFont& f)
232       {
233       //! REVIEW An explanation is needed why only in this one method
234       //! it is assumed that the cursor may not be,
235       //! and that this is a normal situation, and not an exception (no assertion)
236       if (cursor)
237             cursor->setFormat(FormatId::FontFamily, f.family());
238       if (textPalette)
239             textPalette->setFont(f.family());
240       updateText();
241       }
242 
243 //---------------------------------------------------------
244 //   boldClicked
245 //---------------------------------------------------------
246 
boldClicked(bool val)247 void TextTools::boldClicked(bool val)
248       {
249       IF_ASSERT_FAILED(cursor) {
250             return;
251             }
252       cursor->setFormat(FormatId::Bold, val);
253       updateText();
254       }
255 
256 //---------------------------------------------------------
257 //   toggleBold
258 //---------------------------------------------------------
259 
toggleBold()260 void TextTools::toggleBold()
261       {
262       typefaceBold->toggle();
263       boldClicked(typefaceBold->isChecked());
264       }
265 
266 //---------------------------------------------------------
267 //   toggleItalic
268 //---------------------------------------------------------
269 
toggleItalic()270 void TextTools::toggleItalic()
271       {
272       typefaceItalic->toggle();
273       italicClicked(typefaceItalic->isChecked());
274       }
275 
276 //---------------------------------------------------------
277 //   toggleUnderline
278 //---------------------------------------------------------
279 
toggleUnderline()280 void TextTools::toggleUnderline()
281       {
282       typefaceUnderline->toggle();
283       underlineClicked(typefaceUnderline->isChecked());
284       }
285 
286 //---------------------------------------------------------
287 //   underlineClicked
288 //---------------------------------------------------------
289 
underlineClicked(bool val)290 void TextTools::underlineClicked(bool val)
291       {
292       IF_ASSERT_FAILED(cursor) {
293             return;
294             }
295       cursor->setFormat(FormatId::Underline, val);
296       updateText();
297       }
298 
299 //---------------------------------------------------------
300 //   italicClicked
301 //---------------------------------------------------------
302 
italicClicked(bool val)303 void TextTools::italicClicked(bool val)
304       {
305       IF_ASSERT_FAILED(cursor) {
306             return;
307             }
308       cursor->setFormat(FormatId::Italic, val);
309       updateText();
310       }
311 
312 //---------------------------------------------------------
313 //   subscriptClicked
314 //---------------------------------------------------------
315 
subscriptClicked(bool val)316 void TextTools::subscriptClicked(bool val)
317       {
318       IF_ASSERT_FAILED(cursor) {
319             return;
320             }
321       cursor->setFormat(FormatId::Valign, int(val ? VerticalAlignment::AlignSubScript : VerticalAlignment::AlignNormal));
322       typefaceSuperscript->blockSignals(true);
323       typefaceSuperscript->setChecked(false);
324       typefaceSuperscript->blockSignals(false);
325       updateText();
326       }
327 
328 //---------------------------------------------------------
329 //   superscriptClicked
330 //---------------------------------------------------------
331 
superscriptClicked(bool val)332 void TextTools::superscriptClicked(bool val)
333       {
334       IF_ASSERT_FAILED(cursor) {
335             return;
336             }
337       cursor->setFormat(FormatId::Valign, int(val ? VerticalAlignment::AlignSuperScript : VerticalAlignment::AlignNormal));
338       typefaceSubscript->blockSignals(true);
339       typefaceSubscript->setChecked(false);
340       typefaceSubscript->blockSignals(false);
341       updateText();
342       }
343 
344 //---------------------------------------------------------
345 //   showKeyboardClicked
346 //---------------------------------------------------------
347 
showKeyboardClicked(bool val)348 void TextTools::showKeyboardClicked(bool val)
349       {
350       if (val) {
351             IF_ASSERT_FAILED(cursor) {
352                   return;
353                   }
354             if (textPalette == 0)
355                   textPalette = new TextPalette(mscore);
356             textPalette->setText(text);
357             textPalette->setFont(cursor->format()->fontFamily());
358             textPalette->show();
359             }
360       else {
361             if (textPalette)
362                   textPalette->hide();
363             }
364       }
365 }
366