/************************************************************************
**
**  Copyright (C) 2015-2021 Kevin B. Hendricks, Stratford, Ontario, Canada
**  Copyright (C) 2012-2015 John Schember <john@nachtimwald.com>
**  Copyright (C) 2012      Dave Heiland
**  Copyright (C) 2009-2011 Strahinja Markovic  <strahinja.markovic@gmail.com>
**
**  This file is part of Sigil.
**
**  Sigil is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  Sigil is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Sigil.  If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/

#pragma once
#ifndef SIGIL_H
#define SIGIL_H

#include <QtCore/QSharedPointer>
#include <QtWidgets/QMainWindow>

#include "ui_main.h"
#include "BookManipulation/Book.h"
#include "BookManipulation/BookReports.h"
#include "Dialogs/ClipboardHistorySelector.h"
#include "Dialogs/IndexEditor.h"
#include "Dialogs/Reports.h"
#include "Dialogs/SpellcheckEditor.h"
#include "Dialogs/ViewImage.h"
#include "MainUI/FindReplace.h"
#include "MainUI/TOCModel.h"
#include "Parsers/CSSInfo.h"
#include "Misc/PasteTarget.h"
#include "Misc/SettingsStore.h"
#include "Misc/ValidationResult.h"
#include "MiscEditors/ClipEditorModel.h"
#include "MiscEditors/IndexEditorModel.h"
#include "MiscEditors/SearchEditorModel.h"
#include "Tabs/ContentTab.h"
#include "ViewEditors/ElementIndex.h"
#include "Dialogs/SearchEditor.h"

const int MAX_RECENT_FILES = 5;
const int STATUSBAR_MSG_DISPLAY_TIME = 7000;

class QComboBox;
class QLabel;
class QSignalMapper;
class QSlider;
class QTimer;
class QActionGroup;
class FindReplace;
class TabManager;
class BookBrowser;
class TableOfContents;
class ValidationResultsView;
class PreviewWindow;
class SearchEditor;
class ClipEditor;
class ClipsWindow;
class SelectCharacter;
class ViewImage;
class FlowTab;


/**
 * @mainpage
 * The conversion of all source comments to Doxygen format
 * is in progress. Some files have been converted, others have not.
 *
 * Be patient.
 */


/**
 * The main window of the application.
 * Presents the main user interface with menus, toolbars, editing panes
 * and side panes like the Book Browser.
 *
 * This window is the main entry point to all functionality.
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    /**
     * Constructor.
     *
     * @param openfilepath The path to the file that the window
     *                     should load (new file loaded if empty).
     * @param parent The window's parent object.
     * @param flags The flags used to modify window behavior.
     */
    MainWindow(const QString &openfilepath = QString(), 
               const QString version = QString(),
               bool is_internal = false, 
               QWidget *parent = 0, 
               Qt::WindowFlags flags = Qt::WindowFlags());

    ~MainWindow();

    // routines to help Find and Replace exchange info with the SearchEditor
    QList<SearchEditorModel::searchEntry*> SearchEditorGetCurrentEntries();
    void SearchEditorRecordEntryAsCompleted(SearchEditorModel::searchEntry* entry);

    void maybe_fixup_dockwidget_geometry(QDockWidget * widget);

    // returns true if MainWindow is Maximized or is FullScreen
    bool isMaxOrFull();

    /**
     * The book currently being edited.
     *
     * @return A shared pointer to the book.
     */
    QSharedPointer<Book> GetCurrentBook();


    /**
     * get BookBrowser for this book
     *
     * @return A pointer to the BookBrowser
     */
    BookBrowser *GetBookBrowser();


    /**
     * Returns a reference to the current content tab.
     *
     * @return A reference to the current content tab.
     */
    ContentTab *GetCurrentContentTab();

    FlowTab *GetCurrentFlowTab();

    /**
     * Returns a list of valid selected HTML resources
     *
     * @return List of valid selected HTML resources
     */
    QList <Resource *> GetBookBrowserSelectedResources();
    QList <Resource *> GetValidSelectedHTMLResources();
    QList <Resource *> GetValidSelectedCSSResources();

    QList <Resource *> GetTabbedHTMLResources();
    QList <Resource *> GetTabbedCSSResources();

    bool RenameClassInHtml(const QString& oldname, const QString& newname);

    /**
     * Returns a list of all HTML resources in book browser order
     *
     * @return List of all HTML resources in book browser order
     */
    QList <Resource *> GetAllHTMLResources();
    QList <Resource *> GetAllCSSResources();

    QList <Resource *> GetOPFResource();
    QList <Resource *> GetNCXResource();

    /**
     * Select resources in the Book Browser
     *
     */
    void SelectResources(QList<Resource *> resources);

    /**
     * The location of the last bookmark.
     */
    struct LocationBookmark {
        QString bookpath;
        QString bv_caret_location_update;
        int cv_cursor_position;
    };

    void CloseAllTabs();

    void SaveTabData();

    SearchEditorModel *GetSearchEditorModel();

    /**
     * Returns a map with keys being extensions of file types
     * we can load, and the values being filters for use in file dialogs.
     *
     * @return The load dialog filters.
     */
    static const QMap<QString, QString> GetLoadFiltersMap();

    /**
     * Loads a book from the file specified.
     *
     * @param fullfilepath The path to the file to load.
     */
    bool LoadFile(const QString &fullfilepath, bool is_internal = false);

    void SetValidationResults(const QList<ValidationResult> &results);

    static void clearMemoryCaches();

    /**
     * Handle warning the user about undefined url fragments when splitting/merging resources.
     */
    bool ProceedWithUndefinedUrlFragments();

    void sizeMenuIcons();

    QString GetCurrentFilePath();

    void DebugCurrentWidgetSizes();

    QString GetMathJaxFolder() { return m_mathjaxfolder; };

    bool UsingAutomate() { return m_UsingAutomate; }

    QString AutomatePluginParameter() { return m_AutomatePluginParameter; }

public slots:

    bool Automate(const QStringList &commands);

    void OpenUrl(const QUrl &url);

    void ScrollCVToFragment(const QString &fragment);

    /**
     * Opens the specified resource in the specified view state.
     */
    void OpenResource(Resource *resource,
                      int line_to_scroll_to = -1,
                      int position_to_scroll_to = -1,
                      const QString &caret_location_to_scroll_to = QString(),
                      const QUrl &fragment = QUrl(),
                      bool precede_current_tab = false);

    void OpenResourceAndWaitUntilLoaded(Resource *resource,
                                        int line_to_scroll_to = -1,
                                        int position_to_scroll_to = -1,
                                        const QString &caret_location_to_scroll_to = QString(),
                                        const QUrl &fragment = QUrl(),
                                        bool precede_current_tab = false);

    bool UpdateManifestProperties();

    bool GenerateNCXGuideFromNav();

    bool RemoveNCXGuideFromEpub3();

    void CreateIndex();

    void runPlugin(QAction *action);

    void ResourcesAddedOrDeletedOrMoved();

    void launchExternalXEditor();

    bool RepoCommit();
    void RepoCheckout(QString bookid="", QString destpath="", QString filename="", bool loadnow=true);
    void RepoDiff(QString bookid="");
    void RepoManage();

    void RunAutomate1();
    void RunAutomate2();
    void RunAutomate3();
    void RunAutomate(const QString &automatefile);

    void EditAutomate1();
    void EditAutomate2();
    void EditAutomate3();
    void EditAutomate(const QString &automatefile);
    
    bool StandardizeEpub();

    void CreateEpubLayout();

signals:
    void SettingsChanged();

protected:
    void showEvent(QShowEvent *event);

    void changeEvent(QEvent * event);

    /**
     * Workaround for Qt 4.8 bug, which does not save/restore window state
     * correctly if maximized at the time of calling saveGeometry().
     */
    void moveEvent(QMoveEvent *event);
    void resizeEvent(QResizeEvent *event);

    /**
     * Overrides the closeEvent handler so we can check
     * for saved status before actually closing.
     *
     * @param event The close event.
     */
    void closeEvent(QCloseEvent *event);

private slots:

    void UpdateLastSizes();

    void RestoreLastNormalGeometry();

    bool AddCover();


    /**
     * Implements New action functionality.
     */
    void New(const QString version = QString());
    void NewDefault();
    void NewEpub2();
    void NewEpub3();

    /**
     * Implements Open action functionality.
     */
    void Open();

    /**
     * Implements Open recent file action functionality.
     */
    void OpenRecentFile();

    /**
     * Implements Save action functionality.
     */
    bool Save();

    /**
     * Implements Save As action functionality.
     */
    bool SaveAs();

    /**
     * Implements Save A Copy action functionality.
     */
    bool SaveACopy();

    void Exit();

    void ShowMessageOnStatusBar(const QString &message = "", int millisecond_duration = STATUSBAR_MSG_DISPLAY_TIME);

    void ShowLastOpenFileWarnings();

    /**
     * Implements Find action functionality.
     */
    void Find();

    /**
     * Implements Go To Line action functionality.
     */
    void GoToLine();

    /**
     * Implements Zoom In action functionality.
     */
    void ZoomIn();

    /**
     * Implements Zoom Out action functionality.
     */
    void ZoomOut();

    /**
     * Implements Zoom Reset action functionality.
     */
    void ZoomReset();

    void IndexEditorDialog(IndexEditorModel::indexEntry *index_entry = NULL);
    void SpellcheckEditorDialog();

    void ReportsDialog();

    bool DeleteCSSStyles(const QString &filename, QList<CSSInfo::CSSSelector *> css_selectors);

    bool DeleteUnusedMedia(bool in_automate = false);
    bool DeleteUnusedStyles(bool in_automate = false);

    void InsertFileDialog();

    void InsertSpecialCharacter();

    void InsertId();

    void InsertHyperlink();

    void MarkForIndex();

    /**
     * Track the last active control that had focus in the MainWindow that
     * is a valid PasteTarget.
     */
    void ApplicationFocusChanged(QWidget *old, QWidget *now);

    void ApplicationPaletteChanged();

    /** 
     *  Quick Launch Plugins via icon button
     */
    void QuickLaunchPlugin(int i);

    /**
     * Some controls (CodeView and combo boxes in F&R) inherit PasteTarget
     * to allow various modeless/popup dialogs like Clipboard History, Clip Editor and
     * Insert Special Characters to insert text into the focused "PasteTarget" control.
     * These two slots will delegate the relevant signal to the current target if any.
     */
    void PasteTextIntoCurrentTarget(const QString &text);
    void PasteClipEntriesIntoCurrentTarget(const QList<ClipEditorModel::clipEntry *> &clips);
    void PasteClipEntriesIntoPreviousTarget(const QList<ClipEditorModel::clipEntry *> &clips);
    void PasteClipIntoCurrentTarget(int clip_number);

    /**
     * Implements the set CodeView functionality.
     */
    void CodeView();

    /**
     * Implements Meta Editor action functionality.
     */
    void MetaEditorDialog();

    /**
     * Implements Search Editor Dialog functionality.
     */
    void SearchEditorDialog(SearchEditorModel::searchEntry *search_entry = NULL);

    void ClipEditorDialog(ClipEditorModel::clipEntry *clip_entry = NULL);

    /**
     * Implements User Guide action functionality.
     */
    void UserGuide();

    /**
     * Implements Donate action functionality.
     */
    void Donate();

    /**
     * Implements Sigil Website action functionality.
     */
    void SigilWebsite();

    /**
     * Implements About action functionality.
     */
    void AboutDialog();

    /**
     * Implements Preferences action functionality.
     */
    void PreferencesDialog();


    /**
     * Implements Preferences action functionality.
     */
    void ManagePluginsDialog();

    /**
     * Implements Validate Epub action functionality.
     */
    bool WellFormedCheckEpub();

    bool ValidateStylesheetsWithW3C();

    bool ReformatAllStylesheets(bool multiple_line_format);

    bool CharLessThan(const QChar &s1, const QChar &s2);

    /**
     * Disconnects all signals to the old tab
     * and reconnects them to the new tab when the
     * current tab is changed.
     *
     * @old_tab The tab that was previously in use.
     * @new_tab The tab that is becoming current.
     */
    void ChangeSignalsWhenTabChanges(ContentTab *old_tab, ContentTab *new_tab);

    /**
     * Updates the toolbars/menus based on current state
     * and updates the tab state if requested
     */
    void UpdateMWState(bool set_tab_state = true);

    /**
     * Updates the toolbars based on current tab state and changes.
     */
    void UpdateUIOnTabChanges();

    /**
     * Updates the menus based on the number of tabs open.
     */
    void UpdateUIOnTabCountChange();

    /**
     * Performs needed changes when the user switches tabs.
     */
    void UpdateUIWhenTabsSwitch();

    /**
     * Set initial state for actions in Code View
     */
    void SetStateActionsCodeView();

    /**
     * Set initial state for actions in CSS files
     */
    void SetStateActionsCSSView();

    /**
     * Set initial state for actions in Raw View
     */
    void SetStateActionsRawView();

    /**
     * Set initial state for actions in Static View
     * (everything dead, used for viewing images etc.)
     */
    void SetStateActionsStaticView();

    void UpdatePreviewRequest();
    void UpdatePreviewCSSRequest();
    void ScrollPreview();
    void UpdatePreview();
    void InspectHTML();

    /**
     * Updates the cursor postion label to refelect the position of the
     * cursor within the text.
     *
     * Use a negative value to to denote an unknown or invalid value.
     *
     * @param line The line the currsor is currently at.
     * @param column The column within the line that the cursor is currently at.
     */
    void UpdateCursorPositionLabel(int line, int column);

    /**
     * Zooms the current view with the new zoom slider value.
     *
     * @param slider_value The new value from the zoom slider.
     */
    void SliderZoom(int slider_value);

    /**
     * Updates the zoom slider to reflect the new zoom factor.
     *
     * @new_zoom_factor The new zoom factor.
     */
    void UpdateZoomSlider(float new_zoom_factor);

    /**
     * Updates the zoom label to reflect the state of the zoom slider.
     * This is needed so the user can see to what zoom value the slider
     * is being dragged to.
     *
     * @param slider_value The new value from the zoom slider.
     */
    void UpdateZoomLabel(int slider_value);

    /**
     * Updates the zoom label to reflect the new zoom factor.
     */
    void UpdateZoomLabel(float new_zoom_factor);

    /**
     * Creates a new tab from the section splitting operation.
     *
     * @param content The content of the "old" tab/resource.
     * @param originating_resource  The original resource from which the content
     *                              was extracted to create the "old" tab/resource.
     * @see FlowTab::SplitSection, FlowTab::OldTabRequest,
     *      Book::CreateSectionBreakOriginalResource
     */
    void CreateSectionBreakOldTab(QString content, HTMLResource *originating_resource);


    /**
     * Updates the selection/highlight in the Book Browser to the resource in the current tab
     *
     * @see BookBrowser::UpdateSelection
     */
    void UpdateBrowserSelectionToTab();

    /**
     * Creates new section/XHTML documents.
     */
    bool SplitOnSGFSectionMarkers();

    void SetAutoSpellCheck(bool new_state);

    /**
     * Reformats all the book's html resources using Book.cpp's ReformatAllHTML() function.
     */
    bool MendPrettifyHTML();
    bool MendHTML();

    void ClearIgnoredWords();

    void RefreshSpellingHighlighting();

    void MergeResources(QList <Resource *> resources);

    void LinkStylesheetsToResources(QList <Resource *> resources);

    void LinkJavascriptsToResources(QList <Resource *> resources);

    void ResourceUpdatedFromDisk(Resource *resource);

    void UpdateWord(QString old_word, QString new_word);
    void FindWord(QString word);

    /**
     * Return a map of stylesheets included/excluded for all given resources
     */
    QList<std::pair<QString, bool>> GetStylesheetsMap(QList<Resource *> resources);

    /**
     * Return the list of stylesheets linked to the given resource
     */
    QStringList GetStylesheetsAlreadyLinked(Resource *resource);

    QList<std::pair<QString, bool>> GetJavascriptsMap(QList<Resource *> resources);
    QStringList GetJavascriptsAlreadyLinked(Resource *resource);


    void RemoveResources(QList<Resource *> resources = QList<Resource *>());

    bool GenerateTOC(bool skip_selector = false);
    bool CreateHTMLTOC();
    void EditTOCDialog();

    void ChangeCasing(QAction* act);

    void MarkSelection();
    void ClearMarkedText(ContentTab *old_tab = NULL);

    void ApplyHeadingStyleToTab(QAction* act);
    void SetPreserveHeadingAttributes(bool new_state);

    void GoBackFromLinkOrStyle();
    void GoToBookmark(LocationBookmark *locationBookmark);

    void GoToLinkedStyleDefinition(const QString &element_name, const QString &style_class_name);

    void ViewImageDialog(const QUrl &url);

    void BookmarkLocation();
    void BookmarkLinkOrStyleLocation();

    void GoToPreviewLocation();

    void ShowPasteClipboardHistoryDialog();

    void SetInsertedFileWatchResourceFile(const QString &pathname);

    void DeleteReportsStyles(QList<BookReports::StyleData *> reports_styles_to_delete);

    void DeleteFilenames(QStringList files_to_delete);

    void OpenFile(QString file_bookpath, int line = -1, int position = -1);

    void UpdateClipsUI();

    /**
     * support for plugins
     */
    void loadPluginsMenu();
    void unloadPluginsMenu();

private:
    void createJumpList();
    void updateToolTipsOnPluginIcons();
    void UpdateClipButton(QAction *ui_action);
    void InsertFiles(const QStringList &selected_images);
    void InsertFilesFromDisk();

    void ResetLinkOrStyleBookmark();
    void ResetLocationBookmark(LocationBookmark *locationBookmark);

    /**
     * Reads all the stored application settings like
     * window position, geometry etc.
     */
    void ReadSettings();

    /**
     * Writes all the stored application settings like
     * window position, geometry etc.
     */
    void WriteSettings();

    /**
     * Gets called on possible saves and asks the user
     * does he want to save.
     * If the user chooses SAVE, we save and continue
     * If the user chooses DISCARD, we don't save and continue
     * If the user chooses CANCEL, we don't save and stop what we were doing
     *
     * @return \c true if we are allowed to proceed with the current operation.
     */
    bool MaybeSaveDialogSaysProceed();

    bool ProceedToOverwrite(const QString &msg, const QString &filename );

    /**
     * Makes the provided book the current one.
     *
     * @param new_book The new book for editing.
     */
    void SetNewBook(QSharedPointer<Book> new_book);

    /**
     * Creates a new, empty book and replaces
     * the current one with it.
     */
    void CreateNewBook(const QString version=QString(), const QStringList &book_paths=QStringList());

    /**
     * Saves the current book to the file specified.
     *
     * @param fullfilepath The path to save to.
     */
    bool SaveFile(const QString &fullfilepath, bool update_current_filename = true);

    /**
     * Performs zoom operations in the views using the default
     * zoom step. Setting zoom_in to \c true zooms the views *in*,
     * and a setting of \c false zooms them *out*. The zoom value
     * is first wrapped to the nearest zoom step (relative to the zoom direction).
     *
     * @param zoom_in If \c true, zooming in. Otherwise zooming out.
     */
    void ZoomByStep(bool zoom_in);

    /**
     * Sets the provided zoom factor on the active view editor.
     * Valid values are between ZOOM_MAX and ZOOM_MIN, others are ignored.
     *
     * @param new_zoom_factor The new zoom factor for the view.
     */
    void ZoomByFactor(float new_zoom_factor);

    /**
     * Converts a zoom factor to a value in the zoom slider range.
     *
     * @param zoom_factor The zoom factor being converted.
     * @return The converted slider range value.
     */
    static int ZoomFactorToSliderRange(float zoom_factor);

    /**
     * Converts a value in the zoom slider range to a zoom factor.
     *
     * @param slider_range_value The slider range value being converted.
     * @return The converted zoom factor value.
     */
    static float SliderRangeToZoomFactor(int slider_range_value);

    float GetZoomFactor();

    /**
     * Returns a map with keys being extensions of file types
     * we can save, and the values being filters for use in file dialogs.
     *
     * @return The save dialog filters.
     */
    static const QMap<QString, QString> GetSaveFiltersMap();

    /**
     * Sets the current file in the window title and also
     * updates the recent files list.
     *
     * @param fullfilepath The path to the currently edited file.
     */
    void UpdateUiWithCurrentFile(const QString &fullfilepath, bool just_name = false);

    /**
     * Selects the appropriate entry in the heading combo box
     * based on the provided name of the element.
     *
     * @param element_name The name of the currently selected element.
     */
    void SelectEntryOnHeadingToolbar(const QString &element_name);

    /**
     * Creates and adds the recent files actions
     * to the File menu.
     */
    void CreateRecentFilesActions();

    /**
     * Updates the recent files actions when the
     * list of files to be listed has changed.
     */
    void UpdateRecentFileActions();

    /**
     * Performs specific changes based on the OS platform.
     */
    void PlatformSpecificTweaks();

    /**
     * Tweak default UI fonts based on the OS platform.
     */
    void SetupUiFont();

    /**
     * Extends the UI with extra widgets and tweaks.
     * Qt Designer is not able to create all the widgets
     * we want in the MainWindow, so we use this function
     * to extend the UI created by the Designer.
     */
    void ExtendUI();

    /**
     * Extends all the icons with 16px versions.
     * The prevents the use of automatic, blurry, scaled
     * down versions that Qt creates.
     */
    void ExtendIconSizes();

    /**
     * Loads the initial file provided to the MainWindow on creation.
     * If a file was provided to be loaded with this main window instance,
     * that file is loaded; if not, or it can't be opened, an empty file
     * is loaded.
     *
     * @param openfilepath The path to the file to load. Can be empty.
     */
    void LoadInitialFile(const QString &openfilepath, const QString version=QString(), bool is_internal = false);

    /**
     * Connects all the required signals to their slots.
     */
    void ConnectSignalsToSlots();

    /**
     * Connects all the UI signals to the provided tab.
     *
     * @param tab The tab to connect the signals.
     */
    void MakeTabConnections(ContentTab *tab);

    /**
     * Disconnects all the UI signals from the provided tab.
     *
     * @param tab The tab from which to disconnect the signals.
     */
    void BreakTabConnections(ContentTab *tab);

    void SetupPreviewTimer();

    void FixDuplicateFilenames();
    void MoveContentFilesToStdFolders();

    ///////////////////////////////
    // PRIVATE MEMBER VARIABLES
    ///////////////////////////////

    /**
     * Warning messages to be displayed to the user after opening a book
     * if non-fatal errors occurred during loading. When Sigil is started
     * with a filename on command line, we must store these for display
     * after the UI main window is visible.
     */
    QStringList m_LastOpenFileWarnings;
    bool m_IsInitialLoad;

    /**
     * The path to the current file loaded.
     */
    QString m_CurrentFilePath;

    /**
     * The name of the current file loaded.
     */
    QString m_CurrentFileName;

    /**
     * The book currently being worked on.
     */
    QSharedPointer<Book> m_Book;

    /**
     * The last folder from which the user opened or saved a file.
     */
    QString m_LastFolderOpen;

    /**
     * The last filename used for Save As Copy
     */
    QString m_SaveACopyFilename;

    /**
     * The last file selected from Insert File, per book
     */
    QString m_LastInsertedFile;

    /**
     * The list of full filepaths
     * for the last MAX_RECENT_FILES files.
     * \c static because on Mac we have many MainWindows
     */
    static QStringList s_RecentFiles;

    /**
     * Array of recent files actions that are in the File menu.
     */
    QAction *m_RecentFileActions[ MAX_RECENT_FILES ];

    /**
     * The tab managing object.
     */
    TabManager *m_TabManager;

    /**
     * The Book Browser pane that lists all the files in the book.
     */
    BookBrowser *m_BookBrowser;

    ClipsWindow *m_Clips;

    /**
     * The find / replace widget.
     */

    FindReplace *m_FindReplace;

    /**
     * The Table of Contents pane that displays a rendered view of the NCX.
     */
    TableOfContents *m_TableOfContents;

    /**
     * The Validation Results pane that lists all the validation problems.
     */
    ValidationResultsView *m_ValidationResultsView;

    PreviewWindow *m_PreviewWindow;

    /**
     * The lable that displays the cursor position.
     * Line and column.
     */
    QLabel *m_lbCursorPosition;

    /**
     * The slider which the user can use to zoom.
     */
    QSlider *m_slZoomSlider;

    /**
     * The label that displays the current zoom factor.
     */
    QLabel *m_lbZoomLabel;

    /**
     * A map with keys being extensions of file types
     * we can load, and the values being filters for use in file dialogs.
     */
    const QMap<QString, QString> c_SaveFilters;

    /**
     * A map with keys being extensions of file types
     * we can save, and the values being filters for use in file dialogs.
     */
    const QMap<QString, QString> c_LoadFilters;

    /**
     * Collects signals and sends specific parameters to the connected slots.
     */
    QActionGroup *m_casingChangeGroup;

    /**
     * The Search Manager dialog
     */
    SearchEditor *m_SearchEditor;

    /**
     * The storage for SearchEditor
     */
    SearchEditorModel *m_SearchEditorModel;

    ClipEditor *m_ClipEditor;

    IndexEditor *m_IndexEditor;
    SpellcheckEditor *m_SpellcheckEditor;

    SelectCharacter *m_SelectCharacter;

    ViewImage *m_ViewImage;

    Reports *m_Reports;

    bool m_preserveHeadingAttributes;

    LocationBookmark *m_LinkOrStyleBookmark;

    ClipboardHistorySelector *m_ClipboardHistorySelector;
    int m_ClipboardHistoryLimit;

    /**
     * The last widget in this window that had focus that inherited PasteTarget.
     */
    PasteTarget *m_LastPasteTarget;

    bool m_ZoomPreview;

    /**
     * Workaround for Qt 4.8 bug, to track the last known window size when not maximized.
     */
    QByteArray m_LastWindowSize;
    QByteArray m_LastState;
    bool m_FirstTime;
    bool m_PendingLastSizeUpdate;
    bool m_SaveLastEnabled;

    QTimer m_PreviewTimer;

    HTMLResource *m_PreviousHTMLResource;
    QString m_PreviousHTMLText;
    QList<ElementIndex> m_PreviousHTMLLocation;

    /**
     * dynamically updated plugin menus and actions
     */
    QMenu *m_menuPlugins;
    QMenu *m_menuPluginsInput;
    QMenu *m_menuPluginsOutput;
    QMenu *m_menuPluginsEdit;
    QMenu *m_menuPluginsValidation;
    QAction *m_actionManagePlugins;

    QStringList m_pluginList;
    bool m_SaveCSS;
    bool m_IsClosing;

    QList<QAction*> m_qlactions;

    QList<QAction*> m_clactions;


    /**
     * Collects signals and sends specific parameters to the connected slots.
     */
    QActionGroup *m_headingActionGroup;

    QString m_mathjaxfolder;

    bool m_FRVisible;

    bool m_UsingAutomate;
    QStringList m_AutomateLog;
    QString m_AutomatePluginParameter;
    
    /**
     * Holds all the widgets Qt Designer created for us.
     */
    Ui::MainWindow ui;
};

#endif // SIGIL_H


