1 /***********************************************************************************************
2     Copyright (C) 2004 by Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>
3                   2008-2012 by Michel Ludwig (michel.ludwig@kdemail.net)
4  ***********************************************************************************************/
5 
6 /***************************************************************************
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  ***************************************************************************/
14 
15 // 2007-03-17 dani
16 //  - select a single LaTeX command with CTRL+MouseDblClick-left
17 //    (such a double click on the middle part '\def' of '\abd\def\ghi'
18 //    will select only '\def\', not the whole text, as it does now)
19 
20 #include "eventfilter.h"
21 
22 #include <QMouseEvent>
23 #include <QKeyEvent>
24 
25 #include <KModifierKeyInfo>
26 #include <KTextEditor/Document>
27 #include <KTextEditor/View>
28 
29 #include "kiledebug.h"
30 #include "editorextension.h"
31 #include "kileconfig.h"
32 
LaTeXEventFilter(KTextEditor::View * view,KileDocument::EditorExtension * edit)33 LaTeXEventFilter::LaTeXEventFilter(KTextEditor::View *view, KileDocument::EditorExtension *edit) : QObject(view), m_view(view), m_edit(edit)
34 {
35     m_modifierKeyInfo = new KModifierKeyInfo(this);
36     readConfig();
37 }
38 
readConfig()39 void LaTeXEventFilter::readConfig()
40 {
41     m_bCompleteEnvironment = KileConfig::completeEnvironment();
42 }
43 
44 // querying the caps lock state directly is currrently not supported by Qt
isCapsLockEnabled()45 bool LaTeXEventFilter::isCapsLockEnabled()
46 {
47     return m_modifierKeyInfo->isKeyLatched(Qt::Key_CapsLock)
48            || m_modifierKeyInfo->isKeyLocked(Qt::Key_CapsLock);
49 }
50 
51 //FIXME: there should be one central place to convert unicode chars to LaTeX;
52 //       also see 'EditorExtension::insertLatexFromUnicode'.
53 // KateViewInternal as a child of KTextEditor::View has the focus
54 // This was set with KTextEditor::View::setFocusProxy(viewInternal)
eventFilter(QObject *,QEvent * e)55 bool LaTeXEventFilter::eventFilter(QObject* /* o */, QEvent *e)
56 {
57     // Handles input method events, i.e. multi-key combinations with international keyboard layouts
58     if (e->type() == QEvent::InputMethod) {
59         QInputMethodEvent *ime = static_cast<QInputMethodEvent*>(e);
60         // Only single chars, please. ime->commitString() holds the non-latex unicode character string
61         if (ime->commitString().size() == 1) {
62             // Extract unicode representation:
63             unsigned short rep = ime->commitString().at(0).unicode();
64             KILE_DEBUG_MAIN << "string= "<< ime->commitString().at(0) << " dec= "<< rep;
65             return m_edit->insertLatexFromUnicode(rep, m_view);
66         }
67     }
68 
69     if (e->type() == QEvent::KeyPress) {
70         QKeyEvent *ke = static_cast<QKeyEvent*>(e);
71         switch(ke->key())
72         {
73         case Qt::Key_QuoteDbl:
74             return m_edit->insertDoubleQuotes(m_view);
75         case Qt::Key_exclamdown:
76             return m_edit->insertSpecialCharacter("!`", m_view);
77         case Qt::Key_cent:
78             return m_edit->insertSpecialCharacter("\\textcent", m_view, "textcomp");
79         case Qt::Key_sterling:
80             return m_edit->insertSpecialCharacter("\\pounds", m_view);
81         case Qt::Key_currency:
82             return m_edit->insertSpecialCharacter("\\textcurrency", m_view, "textcomp");
83         case Qt::Key_yen:
84             return m_edit->insertSpecialCharacter("\\textyen", m_view, "textcomp");
85         case Qt::Key_copyright:
86             return m_edit->insertSpecialCharacter("\\copyright", m_view);
87         case Qt::Key_ordfeminine:
88             return m_edit->insertSpecialCharacter("\\textordfeminine", m_view, "textcomp");
89         case Qt::Key_guillemotleft:
90             return m_edit->insertSpecialCharacter("\\guillemotleft", m_view);
91         case Qt::Key_notsign:
92             return m_edit->insertSpecialCharacter("\\neg", m_view);
93         case Qt::Key_registered:
94             return m_edit->insertSpecialCharacter("\\textregistered", m_view, "textcomp");
95         case Qt::Key_degree:
96             return m_edit->insertSpecialCharacter("^\\circ", m_view);
97         case Qt::Key_plusminus:
98             return m_edit->insertSpecialCharacter("\\pm", m_view);
99         case Qt::Key_mu:
100             return m_edit->insertSpecialCharacter("\\mu", m_view);
101         case Qt::Key_paragraph:
102             return m_edit->insertSpecialCharacter("\\P", m_view);
103         case Qt::Key_guillemotright:
104             return m_edit->insertSpecialCharacter("\\guillemotright", m_view);
105         case Qt::Key_onequarter:
106             return m_edit->insertSpecialCharacter("\\textonequarter", m_view, "textcomp");
107         case Qt::Key_onehalf:
108             return m_edit->insertSpecialCharacter("\\textonehalf", m_view, "textcomp");
109         case Qt::Key_threequarters:
110             return m_edit->insertSpecialCharacter("\\textthreequarter", m_view, "textcomp");
111         case Qt::Key_questiondown:
112             return m_edit->insertSpecialCharacter("?`", m_view);
113         case Qt::Key_multiply:
114             return m_edit->insertSpecialCharacter("\\times", m_view);
115         case Qt::Key_ssharp:
116             return m_edit->insertSpecialCharacter("\\ss{}", m_view);
117         case Qt::Key_Agrave:
118             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
119                 return m_edit->insertSpecialCharacter("\\`A", m_view);
120             }
121             else return m_edit->insertSpecialCharacter("\\`a", m_view);
122         case Qt::Key_Aacute:
123             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
124                 return m_edit->insertSpecialCharacter("\\'A", m_view);
125             }
126             else return m_edit->insertSpecialCharacter("\\'a", m_view);
127         case Qt::Key_Acircumflex:
128             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
129                 return m_edit->insertSpecialCharacter("\\^A", m_view);
130             }
131             else return m_edit->insertSpecialCharacter("\\^a", m_view);
132         case Qt::Key_Atilde:
133             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
134                 return m_edit->insertSpecialCharacter("\\~A", m_view);
135             }
136             else return m_edit->insertSpecialCharacter("\\~a", m_view);
137         case Qt::Key_Adiaeresis:
138             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
139                 return m_edit->insertSpecialCharacter("\\\"A", m_view);
140             }
141             else return m_edit->insertSpecialCharacter("\\\"a", m_view);
142         case Qt::Key_Aring:
143             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
144                 return m_edit->insertSpecialCharacter("\\AA", m_view);
145             }
146             else return m_edit->insertSpecialCharacter("\\aa", m_view);
147         case Qt::Key_AE:
148             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
149                 return m_edit->insertSpecialCharacter("\\AE", m_view);
150             }
151             else return m_edit->insertSpecialCharacter("\\ae", m_view);
152         case Qt::Key_Ccedilla:
153             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
154                 return m_edit->insertSpecialCharacter("\\c{C}", m_view);
155             }
156             else return m_edit->insertSpecialCharacter("\\c{c}", m_view);
157         case Qt::Key_Egrave:
158             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
159                 return m_edit->insertSpecialCharacter("\\`E", m_view);
160             }
161             else return m_edit->insertSpecialCharacter("\\`e", m_view);
162         case Qt::Key_Eacute:
163             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
164                 return m_edit->insertSpecialCharacter("\\'E", m_view);
165             }
166             else return m_edit->insertSpecialCharacter("\\'e", m_view);
167         case Qt::Key_Ecircumflex:
168             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
169                 return m_edit->insertSpecialCharacter("\\^E", m_view);
170             }
171             else return m_edit->insertSpecialCharacter("\\^e", m_view);
172         case Qt::Key_Ediaeresis:
173             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
174                 return m_edit->insertSpecialCharacter("\\\"E", m_view);
175             }
176             else return m_edit->insertSpecialCharacter("\\\"e", m_view);
177         case Qt::Key_Igrave:
178             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
179                 return m_edit->insertSpecialCharacter("\\`I", m_view);
180             }
181             else return m_edit->insertSpecialCharacter("\\`i", m_view);
182         case Qt::Key_Iacute:
183             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
184                 return m_edit->insertSpecialCharacter("\\'I", m_view);
185             }
186             else return m_edit->insertSpecialCharacter("\\'i", m_view);
187         case Qt::Key_Icircumflex:
188             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
189                 return m_edit->insertSpecialCharacter("\\^I", m_view);
190             }
191             else return m_edit->insertSpecialCharacter("\\^i", m_view);
192         case Qt::Key_Idiaeresis:
193             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
194                 return m_edit->insertSpecialCharacter("\\\"I", m_view);
195             }
196             else return m_edit->insertSpecialCharacter("\\\"i", m_view);
197         case Qt::Key_Ntilde:
198             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
199                 return m_edit->insertSpecialCharacter("\\~N", m_view);
200             }
201             else return m_edit->insertSpecialCharacter("\\~n", m_view);
202         case Qt::Key_Ograve:
203             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
204                 return m_edit->insertSpecialCharacter("\\`O", m_view);
205             }
206             else return m_edit->insertSpecialCharacter("\\`o", m_view);
207         case Qt::Key_Oacute:
208             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
209                 return m_edit->insertSpecialCharacter("\\'O", m_view);
210             }
211             else return m_edit->insertSpecialCharacter("\\'o", m_view);
212         case Qt::Key_Ocircumflex:
213             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
214                 return m_edit->insertSpecialCharacter("\\^O", m_view);
215             }
216             else return m_edit->insertSpecialCharacter("\\^o", m_view);
217         case Qt::Key_Otilde:
218             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
219                 return m_edit->insertSpecialCharacter("\\~O", m_view);
220             }
221             else return m_edit->insertSpecialCharacter("\\~o", m_view);
222         case Qt::Key_Odiaeresis:
223             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
224                 return m_edit->insertSpecialCharacter("\\\"O", m_view);
225             }
226             else return m_edit->insertSpecialCharacter("\\\"o", m_view);
227         case Qt::Key_Ugrave:
228             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
229                 return m_edit->insertSpecialCharacter("\\`U", m_view);
230             }
231             else return m_edit->insertSpecialCharacter("\\`u", m_view);
232         case Qt::Key_Uacute:
233             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
234                 return m_edit->insertSpecialCharacter("\\'U", m_view);
235             }
236             else return m_edit->insertSpecialCharacter("\\'u", m_view);
237         case Qt::Key_Ucircumflex:
238             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
239                 return m_edit->insertSpecialCharacter("\\^U", m_view);
240             }
241             else return m_edit->insertSpecialCharacter("\\^u", m_view);
242         case Qt::Key_Udiaeresis:
243             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
244                 return m_edit->insertSpecialCharacter("\\\"U", m_view);
245             }
246             else return m_edit->insertSpecialCharacter("\\\"u", m_view);
247         case Qt::Key_Yacute:
248             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
249                 return m_edit->insertSpecialCharacter("\\'Y", m_view);
250             }
251             else return m_edit->insertSpecialCharacter("\\'y", m_view);
252         case Qt::Key_ydiaeresis:
253             if (ke->modifiers() == Qt::ShiftModifier || isCapsLockEnabled()) {
254                 return m_edit->insertSpecialCharacter("\\\"Y", m_view);
255             }
256             else return m_edit->insertSpecialCharacter("\\\"y", m_view);
257         default:
258             break;
259         }
260 
261         if(m_bCompleteEnvironment && ke->key() == Qt::Key_Return && ke->modifiers() == 0) {
262             return m_edit->eventInsertEnvironment(m_view);
263         }
264     }
265 
266     else if(e->type() == QEvent::MouseButtonDblClick) {
267         QMouseEvent *me = static_cast<QMouseEvent*>(e);
268         if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier) {
269             m_edit->selectWord(KileDocument::EditorExtension::smTex, m_view);
270             return true;
271         }
272     }
273 
274     //pass this event on
275     return false;
276 }
277 
278 
279