1 /***************************************************************************
2  *   2007-2021 by Peter Semiletov <peter.semiletov@gmail.com>                            *
3  *                                                                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 3 of the License, or     *
8  *   (at your option) any later version.                                   *
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                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  **************************************************************************/
20 
21 /*
22 Copyright (C) 2006-2008 Trolltech ASA. All rights reserved.
23 */
24 
25 /*
26 Diego Iastrubni <elcuco@kde.org> //some GPL'ed code from new-editor-diego-3, found on qtcentre forum
27 */
28 
29 /*
30 code from qwriter:
31  *   Copyright (C) 2009 by Gancov Kostya                                   *
32  *   kossne@mail.ru                                                        *
33 */
34 
35 
36 #ifndef DOCUMENT_H
37 #define DOCUMENT_H
38 
39 #include <vector>
40 #include <utility>
41 
42 #include <QPoint>
43 #include <QStatusBar>
44 #include <QMainWindow>
45 #include <QTabWidget>
46 #include <QPlainTextEdit>
47 #include <QSyntaxHighlighter>
48 #include <QMultiHash>
49 
50 #if QT_VERSION >= 0x050000
51 #include <QRegularExpression>
52 #else
53 #include <QRegExp>
54 #endif
55 
56 #if defined (JOYSTICK_SUPPORTED)
57 #include "myjoystick.h"
58 #endif
59 
60 #include "logmemo.h"
61 #include "tio.h"
62 #include "todo.h"
63 
64 
65 using namespace std;
66 
67 
68 class CDox;
69 class CDocument;
70 class CLineNumberArea;
71 
72 
73 class CSyntaxHighlighter: public QSyntaxHighlighter
74 {
75 public:
76 
77   CDocument *document;
78   bool casecare;
79 
80   QString comment_mult;
81   QString comment_single;
82 
83   QTextCharFormat fmt_multi_line_comment;
84 
85   CSyntaxHighlighter (QTextDocument *parent = 0, CDocument *doc = 0, const QString &fname = "none");
86 };
87 
88 
89 #if QT_VERSION < 0x050000
90 class CSyntaxHighlighterQRegExp: public CSyntaxHighlighter
91 {
92   Q_OBJECT
93 
94 protected:
95 
96   void highlightBlock (const QString &text);
97 
98 public:
99 
100   vector <pair <QRegExp, QTextCharFormat> > hl_rules;
101 
102   //QRegExp commentStartExpression;
103   //QRegExp commentEndExpression;
104 
105   pair <QRegExp, bool> comment_start_expr;
106   pair <QRegExp, bool> comment_end_expr;
107 
108 
109   Qt::CaseSensitivity cs;
110 
111   CSyntaxHighlighterQRegExp (QTextDocument *parent = 0, CDocument *doc = 0, const QString &fname = "none");
112   void load_from_xml (const QString &fname);
113 };
114 #endif
115 
116 
117 #if QT_VERSION >= 0x050000
118 class CSyntaxHighlighterQRegularExpression: public CSyntaxHighlighter
119 {
120   Q_OBJECT
121 
122 protected:
123 
124   void highlightBlock (const QString &text);
125 
126 public:
127 
128   vector <pair <QRegularExpression, QTextCharFormat> > hl_rules;
129 
130   QRegularExpression::PatternOptions pattern_opts;
131 
132   pair <QRegularExpression, bool> comment_start_expr;
133   pair <QRegularExpression, bool> comment_end_expr;
134 
135   CSyntaxHighlighterQRegularExpression (QTextDocument *parent = 0, CDocument *doc = 0, const QString &fname = "none");
136   void load_from_xml (const QString &fname);
137 };
138 #endif
139 
140 
141 class CDocument: public QPlainTextEdit
142 {
143   Q_OBJECT
144 
145 private:
146 
147   CLineNumberArea *line_num_area;
148   QList <QTextEdit::ExtraSelection> extra_selections;
149   QTextEdit::ExtraSelection brace_selection;
150 
151 protected:
152 
153   QMimeData* createMimeDataFromSelection() const;
154   bool canInsertFromMimeData (const QMimeData *source) const;
155   void insertFromMimeData (const QMimeData *source);
156   void paintEvent (QPaintEvent *event);
157   void keyPressEvent (QKeyEvent *event);
158   void resizeEvent (QResizeEvent *event);
159   void wheelEvent (QWheelEvent *e);
160 
161 public:
162 
163   CDox *holder; //uplink
164   QWidget *tab_page; //pointer
165 
166   CSyntaxHighlighter *highlighter;
167 
168   QStringList labels;
169 
170   QString eol;
171   QString markup_mode;
172   QString file_name;
173   QString text_to_search;
174   QString charset;
175   QString indent_val;
176 
177   QPoint rect_sel_start; //rect selection
178   QPoint rect_sel_end;   //rect selection
179 
180   QColor current_line_color;
181   QColor brackets_color;
182   QColor margin_color;
183   QColor linenums_bg;
184   QColor text_color;
185   QColor sel_text_color;
186   QColor sel_back_color;
187 
188   bool cursor_xy_visible;
189   bool highlight_current_line;
190   bool hl_brackets;
191   bool draw_margin;
192   bool draw_linenums;
193   bool auto_indent;
194   bool spaces_instead_of_tabs;
195   bool show_tabs_and_spaces;
196 
197   int position;
198   int tab_sp_width; //in spaces
199   int brace_width; //in pixels
200   int margin_pos; //in chars
201   int margin_x;  //in pixels
202 
203   CDocument (CDox *hldr, QWidget *parent = 0);
204   ~CDocument();
205 
206   QString get() const; //return selected text
207   void put (const QString &value); //replace selection or insert text at cursor
208 
209   bool file_open (const QString &fileName, const QString &codec);
210   bool file_save_with_name (const QString &fileName, const QString &codec);
211   bool file_save_with_name_plain (const QString &fileName);
212 
213   int get_tab_idx();
214   QString get_triplex();
215   QString get_filename_at_cursor();
216   QStringList get_words();
217 
218   void goto_pos (int pos);
219 
220   void set_tab_caption (const QString &fileName);
221   void set_hl (bool mode_auto = true, const QString &theext = "txt");
222   void set_markup_mode();
223 
224   void insert_image (const QString &full_path);
225   void reload (const QString &enc);
226 
227   void update_status();
228   void update_title (bool fullname = true);
229   void update_labels();
230 
231   void set_show_linenums (bool enable);
232   void set_show_margin (bool enable);
233   void set_margin_pos (int mp);
234   void set_hl_cur_line (bool enable);
235   void set_hl_brackets (bool enable);
236 
237   void set_word_wrap (bool wrap);
238   bool get_word_wrap();
239 
240   void indent();
241   void un_indent();
242   void calc_auto_indent();
243 
244   void setup_brace_width();
245   void brace_highlight();
246 
247   void update_ext_selections();
248 
249   void rect_block_start();
250   void rect_block_end();
251 
252   bool has_rect_selection() const;
253   void rect_sel_reset();
254   void rect_sel_replace (const QString &s, bool insert = false);
255   void rect_sel_upd();
256   QString rect_sel_get() const;
257   void rect_sel_cut (bool just_del = false);
258 
259   void lineNumberAreaPaintEvent (QPaintEvent *event);
260   int line_number_area_width();
261 
262 public slots:
263 
264   void updateLineNumberAreaWidth();
265   void cb_cursorPositionChanged();
266   void updateLineNumberArea (const QRect &, int);
267   void slot_selectionChanged();
268 };
269 
270 
271 class CDox: public QObject
272 {
273   Q_OBJECT
274 
275 public:
276 
277   QStringList recent_files;
278 
279 //regexp pattern and file name of syntax hl rules
280 #if QT_VERSION >= 0x050000
281   std::vector<std::pair <QRegularExpression, QString> > hl_files;
282 #else
283   std::vector<std::pair <QRegExp, QString> > hl_files;
284 #endif
285 
286   std::vector <CDocument*> items;
287 
288   QHash <QString, QString> markup_modes;
289   QHash <QString, QString> hash_project;
290   QHash <QString, QString> autosave_files;
291 
292   CTioHandler tio_handler;
293   CTodo todo;
294 
295   QString dir_last;
296   QString fname_current_session;
297   QString fname_current_project;
298   QString dir_config;
299   QString fname_crapbook;
300   QString fname_saved_buffers;
301 
302   QString markup_mode;
303   QString recent_list_fname;
304 
305   QLabel *l_status_bar;
306   QLabel *l_charset;
307 
308   CLogMemo *log; //uplink
309   QMainWindow *parent_wnd; //uplink
310   QTabWidget *tab_widget; //uplink
311   QTabWidget *main_tab_widget; //uplink
312   QMenu *menu_recent; //uplink
313   QTimer timer_joystick;
314   QTimer timer_autosave;
315 
316 #if defined(JOYSTICK_SUPPORTED)
317   CJoystick *joystick;
318 #endif
319 
320   CDox();
321   ~CDox();
322 
323   void update_project (const QString &fileName);
324   void reload_recent_list();
325   void add_to_recent (CDocument *d);
326   void update_recent_menu();
327   void update_current_files_menu();
328 
329   void move_cursor (QTextCursor::MoveOperation mo);
330 
331   CDocument* create_new();
332   CDocument* open_file (const QString &fileName, const QString &codec);
333   CDocument* open_file_triplex (const QString &triplex);
334   CDocument* get_document_by_fname (const QString &fileName);
335   CDocument* get_current();
336 
337   void close_by_idx (int i);
338   void close_current();
339 
340   void save_to_session (const QString &fileName);
341   void load_from_session (const QString &fileName);
342 
343   void save_buffers (const QString &fileName);
344   void load_from_buffers (const QString &fileName);
345 
346   void apply_settings();
347   void apply_settings_single (CDocument *d);
348 
349 #if defined(JOYSTICK_SUPPORTED)
350   bool event (QEvent *ev);
351   void handle_joystick_event (CJoystickAxisEvent *ev);
352 #endif
353 
354 
355 public slots:
356 
357   void open_recent();
358   void open_current();
359 
360   void autosave();
361 
362   void move_cursor_up();
363   void move_cursor_down();
364   void move_cursor_left();
365   void move_cursor_right();
366   void move_cursor_x (double v);
367   void move_cursor_y (double v);
368 };
369 
370 
371 class CLineNumberArea: public QWidget
372 {
373 public:
374 
375   CDocument *code_editor; //uplink
376 
QWidget(editor)377   CLineNumberArea (CDocument *editor = 0): QWidget (editor), code_editor (editor) {}
378 
sizeHint()379   QSize sizeHint() const {
380                           return QSize (code_editor->line_number_area_width(), 0);
381                          }
382 
383 protected:
384 
paintEvent(QPaintEvent * event)385   void paintEvent (QPaintEvent *event)
386       {
387        code_editor->lineNumberAreaPaintEvent (event);
388       }
389 
390 };
391 
392 #endif
393