1 /*
2    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
3    All rights reserved.
4 
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8 
9    1. Redistributions of source code must retain the above copyright
10       notice, this list of conditions and the following disclaimer.
11    2. Redistributions in binary form must reproduce the above copyright
12       notice, this list of conditions and the following disclaimer in the
13       documentation and/or other materials provided with the distribution.
14 
15    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26 
27 
28 #include "mainWindow/kpMainWindow.h"
29 #include "kpMainWindowPrivate.h"
30 
31 #include <kwidgetsaddons_version.h>
32 #include <KActionCollection>
33 #include <KSharedConfig>
34 #include <KConfigGroup>
35 #include "kpLogCategories.h"
36 #include <KFontAction>
37 #include <KFontSizeAction>
38 #include <KToolBar>
39 #include <KToggleAction>
40 #include <KLocalizedString>
41 
42 #include "widgets/toolbars/kpColorToolBar.h"
43 #include "kpDefs.h"
44 #include "layers/selections/text/kpTextStyle.h"
45 #include "tools/selection/text/kpToolText.h"
46 #include "widgets/toolbars/kpToolToolBar.h"
47 #include "widgets/toolbars/options/kpToolWidgetOpaqueOrTransparent.h"
48 #include "views/kpZoomedView.h"
49 
50 
51 // private
setupTextToolBarActions()52 void kpMainWindow::setupTextToolBarActions ()
53 {
54     KActionCollection *ac = actionCollection ();
55 
56     d->actionTextFontFamily = ac->add<KFontAction> (QStringLiteral("text_font_family"));
57     d->actionTextFontFamily->setText (i18n ("Font Family"));
58     connect (d->actionTextFontFamily,
59 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 78, 0)
60              &KSelectAction::textTriggered,
61 #else
62              static_cast<void (KFontAction::*)(const QString&)>(&KFontAction::triggered),
63 #endif
64              this, &kpMainWindow::slotTextFontFamilyChanged);
65 
66     d->actionTextFontSize = ac->add<KFontSizeAction> (QStringLiteral("text_font_size"));
67     d->actionTextFontSize->setText (i18n ("Font Size"));
68     connect (d->actionTextFontSize,
69 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 78, 0)
70              &KSelectAction::indexTriggered,
71 #else
72              static_cast<void (KFontSizeAction::*)(int)>(&KFontSizeAction::triggered),
73 #endif
74              this, &kpMainWindow::slotTextFontSizeChanged);
75 
76     d->actionTextBold = ac->add<KToggleAction> (QStringLiteral("text_bold"));
77     d->actionTextBold->setIcon(QIcon::fromTheme(QStringLiteral("format-text-bold")));
78     d->actionTextBold->setText (i18n ("Bold"));
79     connect (d->actionTextBold, &KToggleAction::triggered,
80              this, &kpMainWindow::slotTextBoldChanged);
81 
82     d->actionTextItalic = ac->add<KToggleAction> (QStringLiteral("text_italic"));
83     d->actionTextItalic->setIcon (QIcon::fromTheme(QStringLiteral("format-text-italic")));
84     d->actionTextItalic->setText (i18n ("Italic"));
85     connect (d->actionTextItalic, &KToggleAction::triggered,
86              this, &kpMainWindow::slotTextItalicChanged);
87 
88     d->actionTextUnderline = ac->add<KToggleAction> (QStringLiteral("text_underline"));
89     d->actionTextUnderline->setIcon (QIcon::fromTheme(QStringLiteral("format-text-underline")));
90     d->actionTextUnderline->setText (i18n ("Underline"));
91     connect (d->actionTextUnderline, &KToggleAction::triggered,
92              this, &kpMainWindow::slotTextUnderlineChanged);
93 
94     d->actionTextStrikeThru = ac->add<KToggleAction> (QStringLiteral("text_strike_thru"));
95     d->actionTextStrikeThru->setIcon(QIcon::fromTheme(QStringLiteral("format-text-strikethrough")));
96     d->actionTextStrikeThru->setText (i18n ("Strike Through"));
97     connect (d->actionTextStrikeThru, &KToggleAction::triggered,
98              this, &kpMainWindow::slotTextStrikeThruChanged);
99 
100 
101     readAndApplyTextSettings ();
102 
103 
104     enableTextToolBarActions (false);
105 }
106 
107 // private
readAndApplyTextSettings()108 void kpMainWindow::readAndApplyTextSettings ()
109 {
110     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
111 
112     const QString font (cfg.readEntry (kpSettingFontFamily, QStringLiteral ("Times")));
113     d->actionTextFontFamily->setFont (font);
114 #if DEBUG_KP_MAIN_WINDOW
115     qCDebug(kpLogMainWindow) << "asked setFont to set to=" << font
116               << "- got back=" << d->actionTextFontFamily->font ();
117 #endif
118     d->actionTextFontSize->setFontSize (cfg.readEntry (kpSettingFontSize, 14));
119     d->actionTextBold->setChecked (cfg.readEntry (kpSettingBold, false));
120     d->actionTextItalic->setChecked (cfg.readEntry (kpSettingItalic, false));
121     d->actionTextUnderline->setChecked (cfg.readEntry (kpSettingUnderline, false));
122     d->actionTextStrikeThru->setChecked (cfg.readEntry (kpSettingStrikeThru, false));
123 
124     d->textOldFontFamily = d->actionTextFontFamily->font ();
125     d->textOldFontSize = d->actionTextFontSize->fontSize ();
126 }
127 
128 
129 // public
enableTextToolBarActions(bool enable)130 void kpMainWindow::enableTextToolBarActions (bool enable)
131 {
132 #if DEBUG_KP_MAIN_WINDOW
133     qCDebug(kpLogMainWindow) << "kpMainWindow::enableTextToolBarActions(" << enable << ")";
134 #endif
135 
136     d->actionTextFontFamily->setEnabled (enable);
137     d->actionTextFontSize->setEnabled (enable);
138     d->actionTextBold->setEnabled (enable);
139     d->actionTextItalic->setEnabled (enable);
140     d->actionTextUnderline->setEnabled (enable);
141     d->actionTextStrikeThru->setEnabled (enable);
142 
143     if (textToolBar ())
144     {
145     #if DEBUG_KP_MAIN_WINDOW
146         qCDebug(kpLogMainWindow) << "\thave toolbar - setShown";
147     #endif
148         // COMPAT: KDE4 does not place the Text Tool Bar in a new row, underneath
149         //         the Main Tool Bar, if there isn't enough room.  This makes
150         //         accessing the Text Tool Bar's buttons difficult.
151         textToolBar ()->setVisible (enable);
152     }
153 }
154 
155 
156 // private slot
slotTextFontFamilyChanged()157 void kpMainWindow::slotTextFontFamilyChanged ()
158 {
159 #if DEBUG_KP_MAIN_WINDOW
160     qCDebug(kpLogMainWindow) << "kpMainWindow::slotTextFontFamilyChanged() alive="
161                << d->isFullyConstructed
162                << "fontFamily="
163                << d->actionTextFontFamily->font ()
164                << "action.currentItem="
165                << d->actionTextFontFamily->currentItem ();
166 #endif
167 
168     if (!d->isFullyConstructed) {
169         return;
170     }
171 
172     if (d->toolText && d->toolText->hasBegun ())
173     {
174         toolEndShape ();
175         d->toolText->slotFontFamilyChanged (d->actionTextFontFamily->font (),
176                                            d->textOldFontFamily);
177     }
178 
179     // Since editable KSelectAction's steal focus from view, switch back to mainView
180     // TODO: back to the last view
181     if (d->mainView) {
182         d->mainView->setFocus ();
183     }
184 
185     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
186     cfg.writeEntry (kpSettingFontFamily, d->actionTextFontFamily->font ());
187     cfg.sync ();
188 
189     d->textOldFontFamily = d->actionTextFontFamily->font ();
190 }
191 
192 // private slot
slotTextFontSizeChanged()193 void kpMainWindow::slotTextFontSizeChanged ()
194 {
195 #if DEBUG_KP_MAIN_WINDOW
196     qCDebug(kpLogMainWindow) << "kpMainWindow::slotTextFontSizeChanged() alive="
197                << d->isFullyConstructed
198                << " fontSize="
199                << d->actionTextFontSize->fontSize ();
200 #endif
201 
202     if (!d->isFullyConstructed) {
203         return;
204     }
205 
206     if (d->toolText && d->toolText->hasBegun ())
207     {
208         toolEndShape ();
209         d->toolText->slotFontSizeChanged (d->actionTextFontSize->fontSize (),
210                                          d->textOldFontSize);
211     }
212 
213     // Since editable KSelectAction's steal focus from view, switch back to mainView
214     // TODO: back to the last view
215     if (d->mainView) {
216         d->mainView->setFocus ();
217     }
218 
219     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
220     cfg.writeEntry (kpSettingFontSize, d->actionTextFontSize->fontSize ());
221     cfg.sync ();
222 
223     d->textOldFontSize = d->actionTextFontSize->fontSize ();
224 }
225 
226 // private slot
slotTextBoldChanged()227 void kpMainWindow::slotTextBoldChanged ()
228 {
229 #if DEBUG_KP_MAIN_WINDOW
230     qCDebug(kpLogMainWindow) << "kpMainWindow::slotTextFontBoldChanged() alive="
231                << d->isFullyConstructed
232                << " bold="
233                << d->actionTextBold->isChecked ();
234 #endif
235 
236     if (!d->isFullyConstructed) {
237         return;
238     }
239 
240     if (d->toolText && d->toolText->hasBegun ())
241     {
242         toolEndShape ();
243         d->toolText->slotBoldChanged (d->actionTextBold->isChecked ());
244     }
245 
246     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
247     cfg.writeEntry (kpSettingBold, d->actionTextBold->isChecked ());
248     cfg.sync ();
249 }
250 
251 // private slot
slotTextItalicChanged()252 void kpMainWindow::slotTextItalicChanged ()
253 {
254 #if DEBUG_KP_MAIN_WINDOW
255     qCDebug(kpLogMainWindow) << "kpMainWindow::slotTextFontItalicChanged() alive="
256                << d->isFullyConstructed
257                << " bold="
258                << d->actionTextItalic->isChecked ();
259 #endif
260 
261     if (!d->isFullyConstructed) {
262         return;
263     }
264 
265     if (d->toolText && d->toolText->hasBegun ())
266     {
267         toolEndShape ();
268         d->toolText->slotItalicChanged (d->actionTextItalic->isChecked ());
269     }
270 
271     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
272     cfg.writeEntry (kpSettingItalic, d->actionTextItalic->isChecked ());
273     cfg.sync ();
274 }
275 
276 // private slot
slotTextUnderlineChanged()277 void kpMainWindow::slotTextUnderlineChanged ()
278 {
279 #if DEBUG_KP_MAIN_WINDOW
280     qCDebug(kpLogMainWindow) << "kpMainWindow::slotTextFontUnderlineChanged() alive="
281                << d->isFullyConstructed
282                << " underline="
283                << d->actionTextUnderline->isChecked ();
284 #endif
285 
286     if (!d->isFullyConstructed) {
287         return;
288     }
289 
290     if (d->toolText && d->toolText->hasBegun ())
291     {
292         toolEndShape ();
293         d->toolText->slotUnderlineChanged (d->actionTextUnderline->isChecked ());
294     }
295 
296     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
297     cfg.writeEntry (kpSettingUnderline, d->actionTextUnderline->isChecked ());
298     cfg.sync ();
299 }
300 
301 // private slot
slotTextStrikeThruChanged()302 void kpMainWindow::slotTextStrikeThruChanged ()
303 {
304 #if DEBUG_KP_MAIN_WINDOW
305     qCDebug(kpLogMainWindow) << "kpMainWindow::slotTextStrikeThruChanged() alive="
306                << d->isFullyConstructed
307                << " strikeThru="
308                << d->actionTextStrikeThru->isChecked ();
309 #endif
310 
311     if (!d->isFullyConstructed) {
312         return;
313     }
314 
315     if (d->toolText && d->toolText->hasBegun ())
316     {
317         toolEndShape ();
318         d->toolText->slotStrikeThruChanged (d->actionTextStrikeThru->isChecked ());
319     }
320 
321     KConfigGroup cfg (KSharedConfig::openConfig (), kpSettingsGroupText);
322     cfg.writeEntry (kpSettingStrikeThru, d->actionTextStrikeThru->isChecked ());
323     cfg.sync ();
324 }
325 
326 
327 // public
textToolBar()328 KToolBar *kpMainWindow::textToolBar ()
329 {
330     return toolBar (QStringLiteral("textToolBar"));
331 }
332 
isTextStyleBackgroundOpaque() const333 bool kpMainWindow::isTextStyleBackgroundOpaque () const
334 {
335     if (d->toolToolBar)
336     {
337         kpToolWidgetOpaqueOrTransparent *oot =
338             d->toolToolBar->toolWidgetOpaqueOrTransparent ();
339 
340         if (oot)
341         {
342             return oot->isOpaque ();
343         }
344     }
345 
346     return true;
347 }
348 
349 // public
textStyle() const350 kpTextStyle kpMainWindow::textStyle () const
351 {
352     return kpTextStyle (d->actionTextFontFamily->font (),
353                         d->actionTextFontSize->fontSize (),
354                         d->actionTextBold->isChecked (),
355                         d->actionTextItalic->isChecked (),
356                         d->actionTextUnderline->isChecked (),
357                         d->actionTextStrikeThru->isChecked (),
358                         d->colorToolBar ? d->colorToolBar->foregroundColor () : kpColor::Invalid,
359                         d->colorToolBar ? d->colorToolBar->backgroundColor () : kpColor::Invalid,
360                         isTextStyleBackgroundOpaque ());
361 }
362 
363 // public
setTextStyle(const kpTextStyle & textStyle_)364 void kpMainWindow::setTextStyle (const kpTextStyle &textStyle_)
365 {
366 #if DEBUG_KP_MAIN_WINDOW
367     qCDebug(kpLogMainWindow) << "kpMainWindow::setTextStyle()";
368 #endif
369 
370     d->settingTextStyle++;
371 
372 
373     if (textStyle_.fontFamily () != d->actionTextFontFamily->font ())
374     {
375         d->actionTextFontFamily->setFont (textStyle_.fontFamily ());
376         slotTextFontFamilyChanged ();
377     }
378 
379     if (textStyle_.fontSize () != d->actionTextFontSize->fontSize ())
380     {
381         d->actionTextFontSize->setFontSize (textStyle_.fontSize ());
382         slotTextFontSizeChanged ();
383     }
384 
385     if (textStyle_.isBold () != d->actionTextBold->isChecked ())
386     {
387         d->actionTextBold->setChecked (textStyle_.isBold ());
388         slotTextBoldChanged ();
389     }
390 
391     if (textStyle_.isItalic () != d->actionTextItalic->isChecked ())
392     {
393         d->actionTextItalic->setChecked (textStyle_.isItalic ());
394         slotTextItalicChanged ();
395     }
396 
397     if (textStyle_.isUnderline () != d->actionTextUnderline->isChecked ())
398     {
399         d->actionTextUnderline->setChecked (textStyle_.isUnderline ());
400         slotTextUnderlineChanged ();
401     }
402 
403     if (textStyle_.isStrikeThru () != d->actionTextStrikeThru->isChecked ())
404     {
405         d->actionTextStrikeThru->setChecked (textStyle_.isStrikeThru ());
406         slotTextStrikeThruChanged ();
407     }
408 
409 
410     if (textStyle_.foregroundColor () != d->colorToolBar->foregroundColor ())
411     {
412         d->colorToolBar->setForegroundColor (textStyle_.foregroundColor ());
413     }
414 
415     if (textStyle_.backgroundColor () != d->colorToolBar->backgroundColor ())
416     {
417         d->colorToolBar->setBackgroundColor (textStyle_.backgroundColor ());
418     }
419 
420 
421     if (textStyle_.isBackgroundOpaque () != isTextStyleBackgroundOpaque ())
422     {
423         if (d->toolToolBar)
424         {
425             kpToolWidgetOpaqueOrTransparent *oot =
426                 d->toolToolBar->toolWidgetOpaqueOrTransparent ();
427 
428             if (oot)
429             {
430                 oot->setOpaque (textStyle_.isBackgroundOpaque ());
431             }
432         }
433     }
434 
435 
436     d->settingTextStyle--;
437 }
438 
439 // public
settingTextStyle() const440 int kpMainWindow::settingTextStyle () const
441 {
442     return d->settingTextStyle;
443 }
444 
445