1 /*********
2 *
3 * This file is part of BibleTime's source code, http://www.bibletime.info/.
4 *
5 * Copyright 1999-2016 by the BibleTime developers.
6 * The BibleTime source code is licensed under the GNU General Public License version 2.0.
7 *
8 **********/
9 
10 #include "frontend/display/chtmlwritedisplay.h"
11 
12 #include <QFontComboBox>
13 #include <QMenu>
14 #include <QTextEdit>
15 #include <QToolBar>
16 #include <QToolTip>
17 #include "backend/config/btconfig.h"
18 #include "bibletimeapp.h"
19 #include "frontend/display/btcolorwidget.h"
20 #include "frontend/display/btfontsizewidget.h"
21 #include "frontend/displaywindow/btactioncollection.h"
22 #include "frontend/displaywindow/chtmlwritewindow.h"
23 #include "util/btassert.h"
24 #include "util/btconnect.h"
25 #include "util/cresmgr.h"
26 
27 
28 class BtActionCollection;
29 
30 namespace {
31 const QString CHTMLWriteDisplayFontKey = "HtmlWriteDisplay/font";
32 const QString CHTMLWriteDisplayFontColorKey = "HtmlWriteDisplay/fontColor";
33 }
34 
CHTMLWriteDisplay(CHTMLWriteWindow * parentWindow,QWidget * parent)35 CHTMLWriteDisplay::CHTMLWriteDisplay(CHTMLWriteWindow * parentWindow, QWidget* parent)
36     : CPlainWriteDisplay(parentWindow, parent)
37     , m_handingFormatChangeFromEditor(false)
38 {
39 
40     BtConfig & conf = btConfig();
41     setTextColor(conf.sessionValue(CHTMLWriteDisplayFontColorKey, textColor()));
42     QFont f = conf.sessionValue(CHTMLWriteDisplayFontKey, currentFont());
43     setCurrentFont(f);
44 
45 
46     //--------------------bold toggle-------------------------
47     m_actions.bold = new QAction(
48         CResMgr::displaywindows::writeWindow::boldText::icon(),
49         tr("Bold"),
50         this);
51     m_actions.bold->setCheckable(true);
52     m_actions.bold->setChecked(f.bold());
53     m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::boldText::accel);
54     m_actions.bold->setToolTip( tr("Bold") );
55     BT_CONNECT(m_actions.bold, SIGNAL(toggled(bool)),
56                this,           SLOT(toggleBold(bool)),
57                Qt::DirectConnection);
58 
59     //--------------------italic toggle-------------------------
60     m_actions.italic = new QAction(
61         CResMgr::displaywindows::writeWindow::italicText::icon(),
62         tr("Italic"),
63         this );
64     m_actions.italic->setCheckable(true);
65     m_actions.italic->setChecked(f.italic());
66     m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::italicText::accel);
67     BT_CONNECT(m_actions.italic, SIGNAL(toggled(bool)),
68                this,             SLOT(toggleItalic(bool)),
69                Qt::DirectConnection);
70     m_actions.italic->setToolTip( tr("Italic") );
71 
72     //--------------------underline toggle-------------------------
73     m_actions.underline = new QAction(
74         CResMgr::displaywindows::writeWindow::underlinedText::icon(),
75         tr("Underline"),
76         this );
77     m_actions.underline->setCheckable(true);
78     m_actions.underline->setChecked(f.underline());
79     m_actions.underline->setShortcut(CResMgr::displaywindows::writeWindow::underlinedText::accel);
80     BT_CONNECT(m_actions.underline, SIGNAL(toggled(bool)),
81                this,                SLOT(toggleUnderline(bool)),
82                Qt::DirectConnection);
83     m_actions.underline->setToolTip( tr("Underline") );
84 
85     //--------------------align left toggle-------------------------
86     m_actions.alignLeft = new QAction(
87         CResMgr::displaywindows::writeWindow::alignLeft::icon(),
88         tr("Left"), this);
89     m_actions.alignLeft->setCheckable(true);
90     m_actions.alignLeft->setShortcut(CResMgr::displaywindows::writeWindow::alignLeft::accel);
91     BT_CONNECT(m_actions.alignLeft, SIGNAL(toggled(bool)),
92                this,                SLOT(alignLeft(bool)),
93                Qt::DirectConnection);
94     m_actions.alignLeft->setToolTip( tr("Align left") );
95 
96     //--------------------align center toggle-------------------------
97     m_actions.alignCenter = new QAction(
98         CResMgr::displaywindows::writeWindow::alignCenter::icon(),
99         tr("Center"), this);
100     m_actions.alignCenter->setCheckable(true);
101     m_actions.alignCenter->setShortcut(CResMgr::displaywindows::writeWindow::alignCenter::accel);
102     BT_CONNECT(m_actions.alignCenter, SIGNAL(toggled(bool)),
103                this,                  SLOT(alignCenter(bool)),
104                Qt::DirectConnection);
105     m_actions.alignCenter->setToolTip( tr("Center") );
106 
107     //--------------------align right toggle-------------------------
108     m_actions.alignRight = new QAction(
109         CResMgr::displaywindows::writeWindow::alignRight::icon(),
110         tr("Right"), this);
111     m_actions.alignRight->setCheckable(true);
112     m_actions.alignRight->setShortcut(CResMgr::displaywindows::writeWindow::alignRight::accel);
113     BT_CONNECT(m_actions.alignRight, SIGNAL(toggled(bool)),
114                this,                 SLOT(alignRight(bool)),
115                Qt::DirectConnection);
116     m_actions.alignRight->setToolTip( tr("Align right") );
117 
118     setAcceptRichText(true);
119     setAcceptDrops(true);
120     viewport()->setAcceptDrops(true);
121 
122     BT_CONNECT(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
123                this, SLOT(slotCurrentCharFormatChanged(QTextCharFormat)),
124                Qt::DirectConnection);
125 }
126 
setText(const QString & newText)127 void CHTMLWriteDisplay::setText(const QString & newText) {
128     QTextEdit::setHtml(newText);
129 }
130 
plainText()131 const QString CHTMLWriteDisplay::plainText() {
132     return QTextEdit::toPlainText();
133 }
134 
toggleBold(bool checked)135 void CHTMLWriteDisplay::toggleBold(bool checked) {
136     if (!m_handingFormatChangeFromEditor)
137         setFontWeight(checked ? QFont::Bold : QFont::Normal);
138 }
139 
toggleItalic(bool checked)140 void CHTMLWriteDisplay::toggleItalic(bool checked) {
141     if (!m_handingFormatChangeFromEditor)
142         setFontItalic(checked);
143 }
144 
toggleUnderline(bool checked)145 void CHTMLWriteDisplay::toggleUnderline(bool checked) {
146     if (!m_handingFormatChangeFromEditor)
147         setFontUnderline(checked);
148 }
149 
alignLeft(bool set)150 void CHTMLWriteDisplay::alignLeft(bool set) {
151     if (!m_handingFormatChangeFromEditor && set && (alignment() != Qt::AlignLeft)) {
152         setAlignment(Qt::AlignLeft);
153         alignmentChanged(Qt::AlignLeft);
154     }
155 }
156 
alignCenter(bool set)157 void CHTMLWriteDisplay::alignCenter(bool set) {
158     if (!m_handingFormatChangeFromEditor && set && (alignment() != Qt::AlignHCenter)) {
159         setAlignment(Qt::AlignHCenter);
160         alignmentChanged(Qt::AlignHCenter);
161     }
162 }
163 
alignRight(bool set)164 void CHTMLWriteDisplay::alignRight(bool set) {
165     if (!m_handingFormatChangeFromEditor && set && (alignment() != Qt::AlignRight)) {
166         setAlignment(Qt::AlignRight);
167         alignmentChanged(Qt::AlignRight);
168     }
169 }
170 
171 /** The text's alignment changed. Enable the right buttons. */
alignmentChanged(int a)172 void CHTMLWriteDisplay::alignmentChanged( int a ) {
173     BT_ASSERT(!m_handingFormatChangeFromEditor);
174     bool alignLeft = false;
175     bool alignCenter = false;
176     bool alignRight = false;
177 
178     if (a & Qt::AlignLeft) {
179         alignLeft = true;
180     }
181     else if ((a & Qt::AlignHCenter) || (a & Qt::AlignCenter)) {
182         alignCenter = true;
183     }
184     else if (a & Qt::AlignRight) {
185         alignRight = true;
186     }
187     else {
188         alignLeft = true;
189         qWarning("unknown alignment %i", a);
190     }
191 
192     m_actions.alignLeft->setChecked( alignLeft );
193     m_actions.alignCenter->setChecked( alignCenter );
194     m_actions.alignRight->setChecked( alignRight );
195 }
196 
slotCurrentCharFormatChanged(const QTextCharFormat &)197 void CHTMLWriteDisplay::slotCurrentCharFormatChanged(const QTextCharFormat &) {
198     BT_ASSERT(!m_handingFormatChangeFromEditor);
199     m_handingFormatChangeFromEditor = true;
200     QFont f = currentFont();
201     emit signalFontChanged(f);
202     emit signalFontSizeChanged(f.pointSize());
203     emit signalFontColorChanged(textColor());
204 
205     m_actions.bold->setChecked(f.bold());
206     m_actions.italic->setChecked(f.italic());
207     m_actions.underline->setChecked(f.underline());
208     m_handingFormatChangeFromEditor = false;
209 
210     BtConfig & conf = btConfig();
211     conf.setSessionValue(CHTMLWriteDisplayFontKey, currentFont());
212     conf.setSessionValue(CHTMLWriteDisplayFontColorKey, textColor());
213 }
214 
slotFontSizeChosen(int newSize)215 void CHTMLWriteDisplay::slotFontSizeChosen(int newSize) {
216     if (!m_handingFormatChangeFromEditor)
217         setFontPointSize(static_cast<qreal>(newSize));
218 }
219 
slotFontFamilyChosen(const QFont & font)220 void CHTMLWriteDisplay::slotFontFamilyChosen(const QFont& font) {
221     if (!m_handingFormatChangeFromEditor)
222         setFontFamily(font.family());
223 }
224 
setupToolbar(QToolBar * bar,BtActionCollection * actions)225 void CHTMLWriteDisplay::setupToolbar(QToolBar * bar, BtActionCollection * actions) {
226     Q_UNUSED(actions);
227 
228     QFont f = currentFont();
229 
230     //--------------------font chooser-------------------------
231     QFontComboBox* fontFamilyCombo = new QFontComboBox(this);
232     fontFamilyCombo->setCurrentFont(f);
233     fontFamilyCombo->setToolTip( tr("Font") );
234     bar->addWidget(fontFamilyCombo);
235     BT_CONNECT(fontFamilyCombo, SIGNAL(currentFontChanged(QFont const &)),
236                this,            SLOT(slotFontFamilyChosen(QFont const &)),
237                Qt::DirectConnection);
238     BT_CONNECT(this,            SIGNAL(signalFontChanged(QFont const &)),
239                fontFamilyCombo, SLOT(setCurrentFont(QFont const &)),
240                Qt::DirectConnection);
241 
242     //--------------------font size chooser-------------------------
243     BtFontSizeWidget* fontSizeChooser = new BtFontSizeWidget(this);
244     fontSizeChooser->setFontSize(f.pointSize());
245     fontSizeChooser->setToolTip( tr("Font size") );
246     bar->addWidget(fontSizeChooser);
247     BT_CONNECT(fontSizeChooser, SIGNAL(fontSizeChanged(int)),
248                this,            SLOT(slotFontSizeChosen(int)),
249                Qt::DirectConnection);
250     BT_CONNECT(this,            SIGNAL(signalFontSizeChanged(int)),
251                fontSizeChooser, SLOT(setFontSize(int)), Qt::DirectConnection);
252 
253     //--------------------color button-------------------------
254     BtColorWidget* fontColorChooser = new BtColorWidget();
255     fontColorChooser->setColor(textColor());
256     fontColorChooser->setToolTip(tr("Font color"));
257     bar->addWidget(fontColorChooser);
258     BT_CONNECT(fontColorChooser, SIGNAL(changed(QColor const &)),
259                this,             SLOT(setTextColor(QColor const &)),
260                Qt::DirectConnection);
261     BT_CONNECT(this,             SIGNAL(signalFontColorChanged(QColor const &)),
262                fontColorChooser, SLOT(setColor(QColor)), Qt::DirectConnection);
263 
264     bar->addSeparator();
265 
266     bar->addAction(m_actions.bold);
267     bar->addAction(m_actions.italic);
268     bar->addAction(m_actions.underline);
269 
270     //seperate formatting from alignment buttons
271     bar->addSeparator();
272 
273     bar->addAction(m_actions.alignLeft);
274     bar->addAction(m_actions.alignCenter);
275     bar->addAction(m_actions.alignRight);
276 }
277