1 /************************************************************************
2 **
3 **  Copyright (C) 2015-2021 Kevin B. Hendricks, Stratford, Ontario, Canada
4 **  Copyright (C) 2012      John Schember <john@nachtimwald.com>
5 **  Copyright (C) 2012      Dave Heiland
6 **  Copyright (C) 2012      Grant Drake
7 **  Copyright (C) 2009-2011 Strahinja Markovic  <strahinja.markovic@gmail.com>
8 **
9 **  This file is part of Sigil.
10 **
11 **  Sigil is free software: you can redistribute it and/or modify
12 **  it under the terms of the GNU General Public License as published by
13 **  the Free Software Foundation, either version 3 of the License, or
14 **  (at your option) any later version.
15 **
16 **  Sigil is distributed in the hope that it will be useful,
17 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 **  GNU General Public License for more details.
20 **
21 **  You should have received a copy of the GNU General Public License
22 **  along with Sigil.  If not, see <http://www.gnu.org/licenses/>.
23 **
24 *************************************************************************/
25 
26 #pragma once
27 #ifndef FLOWTAB_H
28 #define FLOWTAB_H
29 
30 #include <QtCore/QUrl>
31 
32 #include "MainUI/MainWindow.h"
33 #include "Misc/Utility.h"
34 #include "MiscEditors/ClipEditorModel.h"
35 #include "MiscEditors/IndexEditorModel.h"
36 #include "Tabs/ContentTab.h"
37 #include "Tabs/WellFormedContent.h"
38 
39 class QUrl;
40 class CodeViewEditor;
41 class HTMLResource;
42 class Resource;
43 class WellFormedCheckComponent;
44 
45 /**
46  * A tab widget used for displaying XHTML section.
47  * It supports raw code view (Code View).
48  */
49 class FlowTab : public ContentTab, public WellFormedContent
50 {
51     Q_OBJECT
52 
53 public:
54 
55     /**
56      * Constructor.
57      *
58      * @param resource The resource this tab will be displaying.
59      * @param fragment The URL fragment ID to which the tab should scroll.
60      * @param line_to_scroll_to To which line should the resource scroll.
61      * @param parent The parent of this QObject.
62      */
63     FlowTab(HTMLResource *resource,
64             const QUrl &fragment,
65             int line_to_scroll_to = -1,
66             int position_to_scroll_to = -1,
67             QString caret_location_to_scroll_to = QString(),
68             bool grab_focus = true,
69             QWidget *parent = 0);
70 
71     ~FlowTab();
72 
73 
74     // Overrides inherited from ContentTabs
75     bool IsModified();
76 
77     bool CutEnabled();
78     bool CopyEnabled();
79     bool PasteEnabled();
80 
81     bool DeleteLineEnabled();
82 
83     bool RemoveFormattingEnabled();
84 
85     bool RemoveTagPairEnabled();
86 
87     bool InsertClosingTagEnabled();
88 
89     bool GoToLinkOrStyleEnabled();
90 
91     bool AddToIndexEnabled();
92     bool MarkForIndexEnabled();
93 
94     bool InsertIdEnabled();
95     bool InsertHyperlinkEnabled();
96 
97     bool InsertSpecialCharacterEnabled();
98     bool ToggleAutoSpellcheckEnabled();
99 
100     bool InsertFileEnabled();
101 
102     QList<ElementIndex> GetCaretLocation();
103     QString GetCaretLocationUpdate() const;
104     void GoToCaretLocation(QList<ElementIndex> location);
105 
106     QString GetDisplayedCharacters();
107     QString GetText();
108 
109     int GetCursorPosition() const;
110     int GetCursorLine() const;
111     int GetCursorColumn() const;
112 
113     float GetZoomFactor() const;
114 
115     void SetZoomFactor(float new_zoom_factor);
116 
117     void UpdateDisplay();
118 
119     Searchable *GetSearchableContent();
120 
121     bool IsLoadingFinished();
122 
123     /**
124      * Scrolls the tab to the specified fragment.
125      *
126      * @param fragment The URL fragment ID to which the tab should scroll.
127      */
128     void ScrollToFragment(const QString &fragment);
129 
130     /**
131      * Scrolls the tab to the specified line (if in Code View).
132      *
133      * @param line The line to scroll to.
134      */
135     void ScrollToLine(int line);
136     void ScrollToPosition(int cursor_position);
137     void ScrollToCaretLocation(QString caret_location_update);
138 
139     /**
140      * Scrolls the tab to the top.
141      */
142     void ScrollToTop();
143 
144     // Overrides inherited from WellFormedContent
145 
146     void AutoFixWellFormedErrors();
147 
148     void TakeControlOfUI();
149 
150     QString GetFilename();
151 
152     QString GetShortPathName();
153 
154     bool BoldChecked();
155     bool ItalicChecked();
156     bool UnderlineChecked();
157     bool StrikethroughChecked();
158     bool SubscriptChecked();
159     bool SuperscriptChecked();
160     bool AlignLeftChecked();
161     bool AlignRightChecked();
162     bool AlignCenterChecked();
163     bool AlignJustifyChecked();
164     bool BulletListChecked();
165     bool NumberListChecked();
166 
167     bool PasteClipNumber(int clip_number);
168     bool PasteClipEntries(QList<ClipEditorModel::clipEntry *>clips);
169 
170     QString GetCaretElementName();
171 
172     void SuspendTabReloading();
173     void ResumeTabReloading();
174 
175 public slots:
176 
177     bool IsDataWellFormed();
178 
179     void Undo();
180     void Redo();
181     void Cut();
182     void Copy();
183     void Paste();
184 
185     void DeleteLine();
186 
187     bool MarkSelection();
188     bool ClearMarkedText();
189 
190     void SplitSection();
191 
192     void InsertSGFSectionMarker();
193 
194     void InsertClosingTag();
195 
196     void InsertFile(QString html);
197 
198     void PrintPreview();
199     void Print();
200 
201     /**
202      * Qt has some nasty inconsistencies on when to focus is fired. In the situation
203      * where we are switching tabs or switching views on a tab we want to ensure
204      * that we consistently force a reload of the tab if it is pending.
205      */
206     void ReloadTabIfPending();
207 
208     // inherited
209     void SaveTabContent();
210     void LoadTabContent();
211 
212     void Bold();
213     void Italic();
214     void Underline();
215     void Strikethrough();
216     void Subscript();
217     void Superscript();
218 
219     void AlignLeft();
220     void AlignCenter();
221     void AlignRight();
222     void AlignJustify();
223 
224     void InsertBulletedList();
225     void InsertNumberedList();
226 
227     void DecreaseIndent();
228     void IncreaseIndent();
229 
230     void TextDirectionLeftToRight();
231     void TextDirectionRightToLeft();
232     void TextDirectionDefault();
233 
234     void RemoveFormatting();
235 
236     void RemoveTagPair();
237 
238     void ChangeCasing(const Utility::Casing casing);
239 
240     void HeadingStyle(const QString &heading_type, bool preserve_attributes);
241 
242     void AddToIndex();
243     bool MarkForIndex(const QString &title);
244 
245     QString GetAttributeId();
246     QString GetAttributeHref();
247     QString GetAttributeIndexTitle();
248 
249     QString GetSelectedText();
250     bool InsertId(const QString &id);
251     bool InsertHyperlink(const QString &url);
252 
253     void GoToLinkOrStyle();
254 
255     void AddMisspelledWord();
256     void IgnoreMisspelledWord();
257 
258     void HighlightWord(QString word, int pos);
259     void RefreshSpellingHighlighting();
260 
261     void HandleViewImage(const QUrl &url);
262 
263 signals:
264 
265     void SelectionChanged();
266 
267     /**
268      * Emitted when a linked is clicked in the Book View.
269      *
270      * @param url The URL of the clicked link.
271      */
272     void LinkClicked(const QUrl &url);
273 
274     void ViewImageRequest(const QUrl &url);
275 
276     /**
277      * Emitted when an "old" tab should be created.
278      * Emitted as part of the section break operation.
279      *
280      * @param content The content of the "old" tab/resource.
281      * @param originating_resource  The original resource from which the content
282      *                              was extracted to create the "old" tab/resource.
283      */
284     void OldTabRequest(QString content, HTMLResource *originating_resource);
285 
286     void OpenClipEditorRequest(ClipEditorModel::clipEntry *clip);
287 
288     void OpenIndexEditorRequest(IndexEditorModel::indexEntry *index);
289 
290     void GoToLinkedStyleDefinitionRequest(const QString &element_name, const QString &style_class_name);
291 
292     void BookmarkLinkOrStyleLocationRequest();
293 
294     void InsertFileRequest();
295 
296     void UpdatePreview();
297     void UpdatePreviewImmediately();
298     void ScrollPreviewImmediately();
299 
300 public slots:
301     void EmitUpdatePreview();
302     void EmitUpdatePreviewImmediately();
303     void EmitScrollPreviewImmediately();
304 
305 private slots:
306 
307     /**
308      * Performs the delayed initialization of the tab.
309      * We perform delayed initialization after the widget is on
310      * the screen. This way, the user perceives less load time.
311      */
312     void DelayedInitialization();
313 
314     /**
315      * Any slots to do with changing of the underlying resource/content should
316      * only be connected after the resource has loaded. Otherwise we do a
317      * whole lot of unnecessary saving and loading.
318      */
319     void DelayedConnectSignalsToSlots();
320 
321     void EmitContentChanged();
322 
323     void EmitUpdateCursorPosition();
324 
325     /**
326      * Receives the signal emitted when an editor loses focus. Ensures that
327      * the editor's content is well-formed and then saves it.
328      *
329      * @param A pointer to the editor.
330      */
331     void LeaveEditor(QWidget *editor);
332 
333     /**
334      * Receives the signal emitted when user settings have changed.
335      */
336     void LoadSettings();
337 
338     // Called when the underlying resource is modified. It is only connected
339     // when the view state is BV and used to know if BV should be reloaded
340     // when the user enters the view. CV is linked to the resource in such a
341     // way that this is unnecessary. The CV linking is not possible in BV.
342     void ResourceModified();
343     void LinkedResourceModified();
344 
345     // Called when the underlying text inside the control is being replaced
346     // Store our caret location as required.
347     void ResourceTextChanging();
348 
349 private:
350     void CreateCodeViewIfRequired(bool is_delayed_load = true);
351 
352     void CodeView();
353 
354     /**
355      * Connects all the required signals to their respective slots.
356      */
357     void ConnectCodeViewSignalsToSlots();
358 
359 
360     ///////////////////////////////
361     // PRIVATE MEMBER VARIABLES
362     ///////////////////////////////
363 
364     /**
365      * The fragment to scroll to after the tab is initialized.
366      */
367     const QUrl m_FragmentToScroll;
368 
369     /**
370      * The line to scroll to after the tab is initialized.
371      */
372     int m_LineToScrollTo;
373 
374     int m_PositionToScrollTo;
375 
376     QString m_CaretLocationToScrollTo;
377 
378     /**
379      * The HTML resource the tab is currently displaying.
380      */
381     HTMLResource *m_HTMLResource;
382 
383     /**
384      * The Code View Editor.
385      * Displays and edits the raw code.
386      */
387     CodeViewEditor *m_wCodeView;
388 
389     /**
390      * The component used to display a dialog about
391      * well-formedness errors.
392      */
393     WellFormedCheckComponent *m_WellFormedCheckComponent;
394 
395     /**
396      * A flag to be used in conjunction with the check for well-formedness which
397      * indicates whether it's safe to reload the tab content.
398      */
399     bool m_safeToLoad;
400 
401     bool m_initialLoad;
402 
403     bool m_grabFocus;
404 
405     bool m_suspendTabReloading;
406 
407     bool m_defaultCaretLocationToTop;
408 
409     int m_LastPosition;
410 };
411 
412 #endif // FLOWTAB_H
413 
414 
415