Documentation for OpenFLUID 2.2.1
WareSrcFileEditor.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2021-2026, INRAE
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID 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 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30  */
31 
32 /**
33  @file WareSrcFileEditor.hpp
34 
35  @author Aline LIBRES <aline.libres@gmail.com>
36  @author Armel THÖNI <armel.thoni@inrae.fr>
37  */
38 
39 #ifndef __OPENFLUID_UIWARESDEV_WARESRCFILEEDITOR_HPP__
40 #define __OPENFLUID_UIWARESDEV_WARESRCFILEEDITOR_HPP__
41 
42 
43 #include <QPlainTextEdit>
44 #include <QTextBlock>
45 #include <QCompleter>
46 #include <QSignalMapper>
47 #include <QMenu>
48 #include <QStack>
49 
50 #include <openfluid/dllexport.hpp>
55 #include <openfluid/ui/config.hpp>
56 
57 
58 namespace openfluid { namespace ui { namespace waresdev {
59 
60 
61 class WareSrcSyntaxHighlighter;
62 
63 
64 class OPENFLUID_API WareSrcFileEditor: public QPlainTextEdit, public WareFileEditor
65 {
66  Q_OBJECT
67 
68 
69  private slots:
70 
71  void updateLineNumberAreaWidth();
72 
73  void highlightCurrentLine();
74 
75  void updateLineNumberArea(const QRect& Rect, int);
76 
77  void onChanged(bool Changed);
78 
79  void onInsertRequested(const QString& Str);
80 
81  void insertCompletion();
82 
83  void onCompletionPopupCurrentRowChanged(const QModelIndex &Current, const QModelIndex& Previous);
84 
85 
86  private:
87 
88  class LineMarker
89  {
90  private:
91 
93  QStringList m_ContentList;
94 
95  QColor Red = QColor(openfluid::ui::config::LINEMARKER_ERRCOLOR);
96  QColor Orange = QColor(openfluid::ui::config::LINEMARKER_WARNCOLOR);
97 
98  public:
99 
100  QRect m_Rect;
101 
102  LineMarker(WareSrcMsgParser::WareSrcMsg::MessageType MsgType, const QString& Content) :
103  m_MajorMarkerType(MsgType)
104  {
105  QString Cleared = Content.trimmed();
106  if (!Cleared.isEmpty())
107  {
108  m_ContentList.append(Cleared);
109  }
110  }
111 
112 
113  // =====================================================================
114  // =====================================================================
115 
116 
117  QColor getColor() const
118  {
120  {
121  return Red;
122  }
123  return Orange;
124  }
125 
126 
127  // =====================================================================
128  // =====================================================================
129 
130 
131  QString getContent() const
132  {
133  if (m_ContentList.isEmpty())
134  {
135  return "";
136  }
137 
138  if (m_ContentList.size() == 1)
139  {
140  return QString("<html>%1</html>").arg(m_ContentList[0]);
141  }
142 
143  return QString("&bull;&nbsp;%1").arg(m_ContentList.join("<br/>&bull;&nbsp;"));
144  }
145 
146 
147  // =====================================================================
148  // =====================================================================
149 
150 
151  void update(WareSrcMsgParser::WareSrcMsg::MessageType MsgType, const QString& Content)
152  {
154  {
155  m_MajorMarkerType = MsgType;
156  }
157 
158  m_ContentList.append(Content.trimmed());
159  }
160  };
161 
162  WareSrcSyntaxHighlighter* mp_SyntaxHighlighter = nullptr;
163 
164 #if (QT_VERSION_MAJOR < 6)
165  QRegExp m_SelectionTagsRegExp;
166  QRegExp m_AllTagsRegExp;
167  QRegExp m_WordPartRegExp;
168 #else
169  QRegularExpression m_SelectionTagsRegExp;
170  QRegularExpression m_AllTagsRegExp;
171  QRegularExpression m_WordPartRegExp;
172 #endif
173 
174  QWidget* mp_LineNumberArea;
175 
176  QColor m_LineColor;
177  QColor m_LineNbAreaColor = QColor("#F8F8FF");
178  QColor m_LineNbTextColor = QColor("#999999");
179 
180  QString m_IndentString;
181 
182  int m_SpaceCharWidth;
183 
185 
186  QSignalMapper* mp_SignalMapper;
187 
188  QMap<QString, QMenu*> m_InsertionMenus;
189 
190  QCompleter* mp_Completer;
191 
192  QMap<QTextBlock, LineMarker> m_LineMarkersByBlock;
193 
194  bool m_ShowLineMarkers = true;
195 
196  struct SelectionData
197  {
198  QTextCursor TextCursor;
199 
200  QTextBlock FirstBlock;
201 
202  int CursorPos;
203 
204  int StartPos;
205 
206  int EndPos;
207  };
208 
209  QString CommentExtraSpaceString = " ";
210 
211  void writeString(const QString& Str, int InitialIndentInSpaceNb);
212 
213  void insertNewLine();
214 
215  bool findString(const QString& StringToFind, QTextDocument::FindFlags Options);
216 
217  bool replaceString(const QString& StringToFind, const QString& StringForReplace, Qt::CaseSensitivity Cs);
218 
219  int getLeadingSpacesCount(const QString& QStr);
220 
221  bool hasCharInBlockBeforePos(int Pos);
222 
223  void selectText(int StartPos, int EndPos);
224 
225  SelectionData createSelectionData();
226 
227  void addLinePrefix(const QString& PrefixStr, const QTextBlock& Block);
228 
229  /**
230  Remove a prefix string from a block text. (It also removes one extra space (if found) after prefix string)
231  If the block text does not start with the prefix string (excluding spaces), it does nothing.
232  @param[in] PrefixStr The prefix string to remove from block text
233  @param[in] Block The block where to remove the prefix string
234  @return the number of characters removed from the block text
235  */
236  int removeLinePrefix(const QString& PrefixStr, const QTextBlock& Block);
237 
238  void addMultilinePrefix(const QString& PrefixStr);
239 
240  void removeMultilinePrefix(const QString& PrefixStr);
241 
242  void handleSelectionCommenting();
243 
244 
245  protected:
246 
247  void resizeEvent(QResizeEvent* Event);
248 
249  void contextMenuEvent(QContextMenuEvent* Event);
250 
251  void keyPressEvent(QKeyEvent* Event);
252 
253 
254  signals :
255 
256  void editorTxtChanged(WareFileEditor* Editor, bool Changed);
257 
258  void editorSaved();
259 
260 
261  public slots :
262 
263  void setShowLineMarkers(bool ShowMarkers);
264 
265 
266  public:
267 
268  WareSrcFileEditor(const QString& FilePath, QWidget* Parent = nullptr);
269 
271 
272  void lineNumberAreaPaintEvent(QPaintEvent* Event);
273 
275 
276  void saveContent();
277 
278  void saveContentToPath(const QString& Path);
279 
281 
282  bool findReplace(FindReplaceDialog::FindReplaceAction Action, const QString& StringToFind,
283  const QString& StringForReplace, QTextDocument::FindFlags Options, QString& Message);
284 
285  QString getSelectedText();
286 
288 
290 
292 
293  void tooltipEvent(const QPoint& Position);
294 
295  void selectLine(int LineNumber);
296 
298 
299  void goToLine();
300 
302 
303  bool isModified();
304 
305  QWidget* getWidget();
306 
307  void copy();
308 
309  void cut();
310 
311  void paste();
312 
313  void setFocus();
314 
315 };
316 
317 
318 // =====================================================================
319 // =====================================================================
320 
321 
322 class LineNumberArea: public QWidget
323 {
324  Q_OBJECT
325 
326  private:
327 
328  WareSrcFileEditor* mp_Editor;
329 
330  QAction* mp_ShowMarkersAction = nullptr;
331 
332 
333  protected:
334 
335  void paintEvent(QPaintEvent* Event)
336  {
337  mp_Editor->lineNumberAreaPaintEvent(Event);
338  }
339 
340 
341  // =====================================================================
342  // =====================================================================
343 
344 
345  bool event(QEvent* Event)
346  {
347  if (Event->type() == QEvent::ToolTip)
348  {
349  QHelpEvent* HelpEvent = static_cast<QHelpEvent*>(Event);
350  mp_Editor->tooltipEvent(HelpEvent->pos());
351  }
352  return QWidget::event(Event);
353  }
354 
355 
356  // =====================================================================
357  // =====================================================================
358 
359 
360  void contextMenuEvent(QContextMenuEvent* Event)
361  {
362  mp_ShowMarkersAction->setChecked(mp_Editor->getShowLineMarkers());
363 
364  QMenu* Menu = new QMenu();
365  Menu->addAction(mp_ShowMarkersAction);
366  Menu->exec(Event->globalPos());
367  delete Menu;
368  }
369 
370 
371  public:
372 
374  QWidget(Editor)
375  {
376  setStyleSheet("QToolTip {min-width:300px;}");
377 
378  mp_Editor = Editor;
379 
380  mp_ShowMarkersAction = new openfluid::ui::common::DefaultAction("Show markers", this);
381  mp_ShowMarkersAction->setCheckable(true);
382 
383  connect(mp_ShowMarkersAction, SIGNAL(triggered(bool)), mp_Editor, SLOT(setShowLineMarkers(bool)));
384  }
385 
386 
387  // =====================================================================
388  // =====================================================================
389 
390 
391  QSize sizeHint() const
392  {
393  return QSize(mp_Editor->lineNumberAreaWidth(), 0);
394  }
395 };
396 
397 
398 } } } // namespaces
399 
400 
401 #endif /* __OPENFLUID_UIWARESDEV_WARESRCFILEEDITOR_HPP__ */
Header of ...
Definition: DefaultAction.hpp:54
QVector< Rule > Rules
Definition: CompletionProvider.hpp:108
FindReplaceAction
Definition: FindReplaceDialog.hpp:68
Definition: WareSrcFileEditor.hpp:323
LineNumberArea(WareSrcFileEditor *Editor)
Definition: WareSrcFileEditor.hpp:373
void paintEvent(QPaintEvent *Event)
Definition: WareSrcFileEditor.hpp:335
QSize sizeHint() const
Definition: WareSrcFileEditor.hpp:391
bool event(QEvent *Event)
Definition: WareSrcFileEditor.hpp:345
void contextMenuEvent(QContextMenuEvent *Event)
Definition: WareSrcFileEditor.hpp:360
Definition: WareFileEditor.hpp:55
Definition: WareSrcFileEditor.hpp:65
void saveContentToPath(const QString &Path)
void contextMenuEvent(QContextMenuEvent *Event)
void editorTxtChanged(WareFileEditor *Editor, bool Changed)
bool findReplace(FindReplaceDialog::FindReplaceAction Action, const QString &StringToFind, const QString &StringForReplace, QTextDocument::FindFlags Options, QString &Message)
void lineNumberAreaPaintEvent(QPaintEvent *Event)
void tooltipEvent(const QPoint &Position)
void resizeEvent(QResizeEvent *Event)
void addLineMessage(WareSrcMsgParser::WareSrcMsg Message)
WareSrcFileEditor(const QString &FilePath, QWidget *Parent=nullptr)
MessageType
Definition: WareSrcMsgParser.hpp:72
Definition: WareSrcSyntaxHighlighter.hpp:55
#define OPENFLUID_API
Definition: dllexport.hpp:86
FilesystemPath Path
Definition: FilesystemPath.hpp:308
Definition: ApplicationException.hpp:47