1 /*********************************************************************************************
2     copyright            : (C) 2004-2007 by Holger Danielsson (holger.danielsson@versanet.de)
3                                2008-2011 by Michel Ludwig (michel.ludwig@kdemail.net)
4                                2012      by Holger Danielsson (holger.danielsson@versanet.de)
5  *********************************************************************************************/
6 
7 /***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #ifndef EDITOREXTENSION_H
17 #define EDITOREXTENSION_H
18 
19 #include <QObject>
20 #include <QRegExp>
21 #include <QString>
22 #include <QStringList>
23 
24 #include <KTextEditor/Document>
25 
26 #include "widgets/structurewidget.h"
27 #include "latexcmd.h"
28 
29 class KileInfo;
30 namespace KileAction {
31 class TagData;
32 }
33 
34 namespace KileDocument
35 {
36 
37 class EditorExtension : public QObject
38 {
39     Q_OBJECT
40 
41 public:
42     explicit EditorExtension(KileInfo *);
43     ~EditorExtension();
44 
45     enum EnvType {EnvNone, EnvList, EnvTab, EnvCrTab};
46 
47     enum SelectMode {smTex, smLetter, smWord, smNospace};
48 
49     void readConfig();
50 
51     void insertTag(const KileAction::TagData& data, KTextEditor::View *view);
52 
53     QString getTextLineReal(KTextEditor::Document *doc, int row);
54     void gotoBullet(bool backwards, KTextEditor::View *view = Q_NULLPTR);
55     void selectLine(int line,KTextEditor::View *view = Q_NULLPTR);
56     bool replaceLine(int line, const QString &s, KTextEditor::View *view = Q_NULLPTR);
57 
58     void gotoEnvironment(bool backwards, KTextEditor::View *view = Q_NULLPTR);
59     void matchEnvironment(KTextEditor::View *view = Q_NULLPTR);
60     void closeEnvironment(KTextEditor::View *view = Q_NULLPTR);
61     void closeAllEnvironments(KTextEditor::View *view = Q_NULLPTR);
62     void selectEnvironment(bool inside, KTextEditor::View *view = Q_NULLPTR);
63     void deleteEnvironment(bool inside, KTextEditor::View *view = Q_NULLPTR);
autoIndentEnvironment()64     QString autoIndentEnvironment() {
65         return m_envAutoIndent;
66     }
67 
68     bool hasTexgroup(KTextEditor::View *view = Q_NULLPTR);
69     void gotoTexgroup(bool backwards, KTextEditor::View *view = Q_NULLPTR);
70     void selectTexgroup(bool inside, KTextEditor::View *view = Q_NULLPTR);
71     void deleteTexgroup(bool inside, KTextEditor::View *view = Q_NULLPTR);
72     KTextEditor::Range texgroupRange(bool inside=true, KTextEditor::View *view = Q_NULLPTR);
73     QString getTexgroupText(bool inside=true, KTextEditor::View *view = Q_NULLPTR);
74 
75     /**
76      * Returns a (potentially) translated list of options for inserting double quotes
77      */
doubleQuotesListI18N()78     const QStringList doubleQuotesListI18N() {
79         return m_quoteListI18N;
80     }
81 
82     // get current word
83     bool getCurrentWord(KTextEditor::Document *doc, int row, int col, SelectMode mode, QString &word, int &x1, int &x2);
84     QString getEnvironmentText(int &row, int &col, QString &name, KTextEditor::View *view = Q_NULLPTR);
85     bool hasEnvironment(KTextEditor::View *view = Q_NULLPTR);
86 
87     KTextEditor::Range environmentRange(bool inside=false, KTextEditor::View *view = Q_NULLPTR);
88     QString environmentName(KTextEditor::View *view = Q_NULLPTR);
89     QString environmentText(bool inside=false, KTextEditor::View *view = Q_NULLPTR);
90 
91     KTextEditor::Range wordRange(const KTextEditor::Cursor &cursor, bool latexCommand=false, KTextEditor::View *view = Q_NULLPTR);
92     QString word(const KTextEditor::Cursor &cursor, bool latexCommand=false, KTextEditor::View *view = Q_NULLPTR);
93 
94     KTextEditor::Range findCurrentParagraphRange(KTextEditor::View *view, bool wholeLines = true);
95     QString getParagraphText(KTextEditor::View *view);
96     int prevNonEmptyLine(int line, KTextEditor::View *view = Q_NULLPTR);
97     int nextNonEmptyLine(int line, KTextEditor::View *view = Q_NULLPTR);
98 
99     // complete environment
100     bool eventInsertEnvironment(KTextEditor::View *view);
101 
102     // mathgroup
103     QString getMathgroupText(uint &row, uint &col, KTextEditor::View *view = Q_NULLPTR);
104     QString getMathgroupText(KTextEditor::View *view = Q_NULLPTR);
105     bool hasMathgroup(KTextEditor::View *view = Q_NULLPTR);
106     KTextEditor::Range  mathgroupRange(KTextEditor::View *view = Q_NULLPTR);
107 
108     bool moveCursorRight(KTextEditor::View *view = Q_NULLPTR);
109     bool moveCursorLeft(KTextEditor::View *view = Q_NULLPTR);
110     bool moveCursorUp(KTextEditor::View *view = Q_NULLPTR);
111     bool moveCursorDown(KTextEditor::View *view = Q_NULLPTR);
112 
113 public Q_SLOTS:
114     void insertIntelligentNewline(KTextEditor::View *view = Q_NULLPTR);
115 
selectEnvInside()116     void selectEnvInside() {
117         selectEnvironment(true);
118     }
selectEnvOutside()119     void selectEnvOutside() {
120         selectEnvironment(false);
121     }
deleteEnvInside()122     void deleteEnvInside() {
123         deleteEnvironment(true);
124     }
deleteEnvOutside()125     void deleteEnvOutside() {
126         deleteEnvironment(false);
127     }
gotoBeginEnv()128     void gotoBeginEnv() {
129         gotoEnvironment(true);
130     }
gotoEndEnv()131     void gotoEndEnv() {
132         gotoEnvironment(false);
133     }
matchEnv()134     void matchEnv() {
135         matchEnvironment();
136     }
closeEnv()137     void closeEnv() {
138         closeEnvironment();
139     }
closeAllEnv()140     void closeAllEnv() {
141         closeAllEnvironments();
142     }
143 
selectTexgroupInside()144     void selectTexgroupInside() {
145         selectTexgroup(true);
146     }
selectTexgroupOutside()147     void selectTexgroupOutside() {
148         selectTexgroup(false);
149     }
deleteTexgroupInside()150     void deleteTexgroupInside() {
151         deleteTexgroup(true);
152     }
deleteTexgroupOutside()153     void deleteTexgroupOutside() {
154         deleteTexgroup(false);
155     }
gotoBeginTexgroup()156     void gotoBeginTexgroup() {
157         gotoTexgroup(true);
158     }
gotoEndTexgroup()159     void gotoEndTexgroup() {
160         gotoTexgroup(false);
161     }
162     void matchTexgroup(KTextEditor::View *view = Q_NULLPTR);
163     void closeTexgroup(KTextEditor::View *view = Q_NULLPTR);
164 
165     void selectParagraph(KTextEditor::View *view = Q_NULLPTR, bool wholeLines = true);
166     void selectLine(KTextEditor::View *view = Q_NULLPTR);
167     void selectLines(int from, int to, KTextEditor::View *view = Q_NULLPTR);
168     void selectWord(SelectMode mode = smTex, KTextEditor::View *view = Q_NULLPTR);
169     void deleteParagraph(KTextEditor::View *view = Q_NULLPTR);
170     void deleteEndOfLine(KTextEditor::View *view = Q_NULLPTR);
171     void deleteWord(SelectMode mode = smTex, KTextEditor::View *view = Q_NULLPTR);
172 
173     void selectMathgroup(KTextEditor::View *view = Q_NULLPTR);
174     void deleteMathgroup(KTextEditor::View *view = Q_NULLPTR);
175 
176     void nextBullet(KTextEditor::View* view = Q_NULLPTR);
177     void prevBullet(KTextEditor::View* view = Q_NULLPTR);
178     void insertBullet(KTextEditor::View* view = Q_NULLPTR);
179 
180     void gotoNextParagraph(KTextEditor::View *view = Q_NULLPTR);
181     void gotoPrevParagraph(KTextEditor::View *view = Q_NULLPTR);
182 
183     void gotoNextSectioning();
184     void gotoPrevSectioning();
185     void gotoSectioning(bool backwards, KTextEditor::View *view = Q_NULLPTR);
186     void sectioningCommand(KileWidget::StructureViewItem *item, int id);
187 
188     bool insertDoubleQuotes(KTextEditor::View *view = Q_NULLPTR);
189     void initDoubleQuotes();
190 
191     bool insertLatexFromUnicode(unsigned short rep, KTextEditor::View *view);
192     bool insertSpecialCharacter(const QString& texString, KTextEditor::View *view = Q_NULLPTR, const QString& dep = "");
193 
194     void insertIntelligentTabulator(KTextEditor::View *view = Q_NULLPTR);
195 
196     void moveCursorToLastPositionInCurrentLine(KTextEditor::View *view = Q_NULLPTR);
197     void keyReturn(KTextEditor::View *view = Q_NULLPTR);
198     void commentLaTeX(KTextEditor::Document* document, const KTextEditor::Range &range);
199 
200     void goToLine(int line, KTextEditor::View *view = Q_NULLPTR);
201 
202 private:
203 
204     enum EnvTag {EnvBegin, EnvEnd};
205 
206     enum EnvPos {EnvLeft, EnvInside, EnvRight};
207 
208     enum MathTag {mmNoMathMode, mmMathDollar, mmMathParen, mmDisplaymathParen, mmMathEnv, mmDisplaymathEnv};
209 
210     enum CursorMove {MoveCursorLeft, MoveCursorRight, MoveCursorUp, MoveCursorDown};
211 
212     struct EnvData {
213         int row;
214         int col;
215         QString name;
216         int len;
217         EnvPos cpos;
218         EnvTag tag;
219         EnvType type;
220     };
221 
222     struct MathData {
223         int row;
224         int col;
225         int len;
226         unsigned int numdollar;
227         MathTag tag;
228         QString envname;
229     };
230 
231     struct BracketData {
232         int row;
233         int col;
234         bool open;
235     };
236 
237     QRegExp m_reg;
238     bool m_overwritemode;
239     QString m_envAutoIndent;
240 
241     KileInfo	*m_ki;
242 
243     // complete environments
244     QRegExp m_regexpEnter;
245 
246     // double Quotes
247     bool m_dblQuotes;
248     QStringList m_quoteListI18N;
249     QList<QPair<QString, QString> > m_quoteList;
250     QString m_leftDblQuote, m_rightDblQuote;
251 
252     // special chars
253     bool m_specialCharacters;
254 
255     // change cursor position
256     bool increaseCursorPosition(KTextEditor::Document *doc, int &row, int &col);
257     bool decreaseCursorPosition(KTextEditor::Document *doc, int &row, int &col);
258     bool moveCursor(KTextEditor::View *view, CursorMove direction);
259 
260     // check position
261     bool isValidBackslash(KTextEditor::Document *doc, int row, int col);
262     bool isCommentPosition(KTextEditor::Document *doc, int row, int col);
263     bool isEnvironmentPosition(KTextEditor::Document *doc, int row, int col,EnvData &env);
264 
265     // find environment tags
266     bool findBeginEnvironment(KTextEditor::Document *doc, int row, int col, EnvData &env);
267     bool findEndEnvironment(KTextEditor::Document *doc, int row, int col, EnvData &env);
268     bool findEnvironmentTag(KTextEditor::Document *doc, int row, int col, EnvData &env, bool backwards = false);
269     bool findOpenedEnvironment(int &row, int &col, QString &envname, KTextEditor::View *view);
270     QStringList findOpenedEnvironmentList(KTextEditor::View *view, bool position = false);
271 
272     // get current environment
273     bool getEnvironment(bool inside, EnvData &envbegin, EnvData &envend,KTextEditor::View *view);
274     bool expandSelectionEnvironment(bool inside, KTextEditor::View *view);
275 
276     // find brackets
277     bool isBracketPosition(KTextEditor::Document *doc, int row, int col, BracketData &bracket);
278     bool findOpenBracket(KTextEditor::Document *doc, int row, int col, BracketData &bracket);
279     bool findCloseBracket(KTextEditor::Document *doc, int row, int col, BracketData &bracket);
280     bool findCloseBracketTag(KTextEditor::Document *doc, int row, int col,BracketData &bracket);
281     bool findOpenBracketTag(KTextEditor::Document *doc, int row, int col, BracketData &bracket);
282 
283     // find math tags
284     bool isOpeningMathTagPosition(KTextEditor::Document *doc, uint row, uint col, MathData &mathdata);
285     bool isClosingMathTagPosition(KTextEditor::Document *doc, uint row, uint col, MathData &mathdata);
286     bool findOpenMathTag(KTextEditor::Document *doc, int row, int col, MathData &mathdata);
287     bool findCloseMathTag(KTextEditor::Document *doc, int row, int col, MathData &mathdata);
288     bool checkMathtags(const MathData &begin,const MathData &end);
289 
290     // mathgroup
291     bool getMathgroup(KTextEditor::View *view, int &row1, int &col1, int &row2, int &col2);
292 
293     // get current Texgroup
294     bool getTexgroup(bool inside, BracketData &open, BracketData &close, KTextEditor::View *view);
295 
296     // find current paragraph
297     bool findCurrentTexParagraph(int &startline, int &endline, KTextEditor::View *view);
298     bool findCurrentTexParagraph(int &startline, int& startcolumn, int &endline, int& endcolumn, KTextEditor::View *view);
299 
300     // sectioning commands
301     bool findEndOfDocument(KTextEditor::Document *doc, int row, int col, int &rowFound, int &colFound);
302 
303     // check environment type
304     KileDocument::LatexCommands *m_latexCommands;
305     bool shouldCompleteEnv(const QString &envname, KTextEditor::View *view);
306     QString getWhiteSpace(const QString &s);
307 
308     // verbatim text
309     bool insideVerb(KTextEditor::View *view);
310     bool insideVerbatim(KTextEditor::View *view);
311 
312     // help
313     void readHelpList(QString const &filename);
314 
315     KTextEditor::View *determineView(KTextEditor::View *view);
316     void deleteRange(KTextEditor::Range &range, KTextEditor::View *view);
317 
318     QString extractIndentationString(KTextEditor::View *view, int line);
319 };
320 
321 }
322 
323 #endif
324