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