/* Copyright (C) 2012 Sebastian Herbord. All rights reserved. This file is part of Mod Organizer. Mod Organizer 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. Mod Organizer 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 Mod Organizer. If not, see . */ #ifndef MODINFODIALOG_H #define MODINFODIALOG_H #include "filerenamer.h" #include "modinfo.h" #include "modinfodialogfwd.h" #include "tutorabledialog.h" namespace Ui { class ModInfoDialog; } namespace MOShared { class FilesOrigin; } class PluginContainer; class OrganizerCore; class Settings; class ModInfoDialogTab; class ModListView; /** * this is a larger dialog used to visualise information about the mod. * @todo this would probably a good place for a plugin-system **/ class ModInfoDialog : public MOBase::TutorableDialog { Q_OBJECT; // creates a tab, it's a friend because it uses a bunch of member variables // to create ModInfoDialogTabContext // template friend std::unique_ptr createTab(ModInfoDialog& d, ModInfoTabIDs index); public: ModInfoDialog(OrganizerCore& core, PluginContainer& plugin, ModInfo::Ptr mod, ModListView* view, QWidget* parent = nullptr); ~ModInfoDialog(); // switches to the tab with the given id // void selectTab(ModInfoTabIDs id); // updates all tabs, selects the initial tab, opens the dialog and // saves/restores geometry // int exec() override; signals: // emitted when a tab changes the origin // void originModified(int originID); // emitted when the mod of the dialog is changed // void modChanged(unsigned int modIndex); protected: // forwards to tryClose() // void closeEvent(QCloseEvent* e); private: // represents a single tab // struct TabInfo { // tab implementation std::unique_ptr tab; // actual position in the tab bar, updated every time a tab is moved int realPos; // widget used by the QTabWidget for this tab // // because QTabWidget doesn't support simply hiding tabs, they have to be // completely removed from the widget when they don't support the current // mod // // therefore, `widget, `caption` and `icon` are remembered so tabs can be // removed and re-added when navigating between mods // // `widget` is also used figure out which tab is where when they're // re-ordered QWidget* widget; // caption for this tab, see `widget` QString caption; // icon for this tab, see `widget` QIcon icon; TabInfo(std::unique_ptr tab); // returns whether this tab is part of the tab widget // bool isVisible() const; }; std::unique_ptr ui; OrganizerCore& m_core; PluginContainer& m_plugin; ModListView* m_modListView; ModInfo::Ptr m_mod; std::vector m_tabs; // initial tab requested by the main window when the dialog is opened; whether // the request can be honoured depends on what tabs are present ModInfoTabIDs m_initialTab; // set to true when tabs are being removed and re-added while navigating // between mods; since the current index changes while this is happening, // onTabSelectionChanged() will be called repeatedly // // however, it will check this flag and ignore the event so first activations // are not fired incorrectly bool m_arrangingTabs; // creates all the tabs and connects events // void createTabs(); // saves the dialog state and calls saveState() on all tabs // void saveState() const; // restores the dialog state and calls restoreState() on all tabs // void restoreState(); // sets the currently selected mod; resets first activation, but doesn't // update anything // void setMod(ModInfo::Ptr mod); // sets the currently selected mod, if found; forwards to setMod() above // void setMod(const QString& name); // returns the origin of the current mod, may be null // MOShared::FilesOrigin* getOrigin(); // returns the currently selected tab, taking re-ordering in to account; // shouldn't be null, but could be // TabInfo* currentTab(); // fully updates the dialog; sets the title, the tab visibility and updates // all the tabs; used when the current mod changes // // see setTabsVisibility() for firstTime // void update(bool firstTime = false); // builds the list of visible tabs; if the list is different from what's // currently displayed, or firstTime is true, forwards to reAddTabs() void setTabsVisibility(bool firstTime); // clears the tab widgets and re-adds the tabs having the visible flag in // the given vector, following the tab order from the settings // void reAddTabs(const std::vector& visibility, ModInfoTabIDs sel); // called by update(); clears tabs, feeds files and calls update() on all // tabs, then setTabsColors() // void updateTabs(bool becauseOriginChanged = false); // goes through all files on the filesystem for the current mod and calls // feedFile() on every tab until one accepts it // void feedFiles(std::vector& interestedTabs); // goes through all tabs and sets the tab text colour depending on whether // they have data or not // void setTabsColors(); // called when the delete key is pressed anywhere in the dialog; forwards to // ModInfoDialogTab::deleteRequest() for the currently selected tab // void onDeleteShortcut(); // finds the tab with the given id and selects it // void switchToTab(ModInfoTabIDs id); // saves the current tab order; used by saveState(), but also by // setTabsVisibility() to make sure any changes to order are saved before // re-adding tabs // void saveTabOrder() const; // asks all the tabs if they accept closing the dialog, returns false if one // objected // bool tryClose(); // called when the user clicks the close button; closing the dialog by other // means ends up in closeEvent(); forwards to tryClose() // void onCloseButton(); // called when the user clicks the previous button; asks the main window for // the previous mod in the list and loads it // void onPreviousMod(); // called when the user clicks the next button; asks the main window for the // next mod in the list and loads it // void onNextMod(); // called when the selects a tab; handles first activation // void onTabSelectionChanged(); // called when the user re-orders tabs; sets the correct TabInfo::realPos for // all tabs // void onTabMoved(); // called when a tab has modified the origin; emits originModified() and // updates all the tabs that use origin files // void onOriginModified(int originID); }; #endif // MODINFODIALOG_H