From 46c365c388f204d898c672439fdf82b21a762903 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 15 Feb 2019 01:00:38 -0800 Subject: [PATCH] added more documentation --- mainwindow.cpp | 8 +-- mainwindow.h | 134 ++++++++++++++++++++++++++++++++++++- oliveglobal.cpp | 3 +- oliveglobal.h | 149 ++++++++++++++++++++++++++++++++++++++++- ui/focusfilter.cpp | 5 +- ui/focusfilter.h | 161 +++++++++++++++++++++++++++++++++++++++++++++ ui/menuhelper.cpp | 5 ++ ui/menuhelper.h | 82 +++++++++++++++++++++++ 8 files changed, 533 insertions(+), 14 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index f94db8ff9..1ba325b3e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -286,7 +286,7 @@ void kbd_shortcut_processor(QByteArray& file, QMenu* menu, bool save, bool first } } -void MainWindow::load_shortcuts(const QString& fn, bool first) { +void MainWindow::load_shortcuts(const QString& fn) { QByteArray shortcut_bytes; QFile shortcut_path(fn); if (shortcut_path.exists() && shortcut_path.open(QFile::ReadOnly)) { @@ -296,7 +296,7 @@ void MainWindow::load_shortcuts(const QString& fn, bool first) { QList menus = menuBar()->actions(); for (int i=0;imenu(); - kbd_shortcut_processor(shortcut_bytes, menu, false, first); + kbd_shortcut_processor(shortcut_bytes, menu, false, true); } } @@ -727,7 +727,7 @@ void MainWindow::setup_menus() { help_menu->addAction(tr("&About..."), Olive::Global.data(), SLOT(open_about_dialog()))->setProperty("id", "about"); - load_shortcuts(get_config_path() + "/shortcuts", true); + load_shortcuts(get_config_path() + "/shortcuts"); } void MainWindow::updateTitle() { @@ -919,7 +919,7 @@ void MainWindow::fileMenu_About_To_Be_Shown() { QAction* action = open_recent->addAction(recent_projects.at(i)); action->setProperty("keyignore", true); action->setData(i); - connect(action, SIGNAL(triggered()), Olive::Global.data(), SLOT(open_recent())); + connect(action, SIGNAL(triggered()), &Olive::MenuHelper, SLOT(open_recent_from_menu())); } open_recent->addSeparator(); diff --git a/mainwindow.h b/mainwindow.h index 79c216a70..b79ea0293 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -14,38 +14,168 @@ public: explicit MainWindow(QWidget *parent); virtual ~MainWindow() override; + /** + * @brief Update window title + * + * Updates the window title to reflect the current project filename. Call if the project filename changes. + * + * NOTE: It's recommended to use update_project_filename() from Olive::Global to update the filename completely + * instead of calling this function directly (update_project_filename() calls this function in the process). + */ void updateTitle(); - void load_shortcuts(const QString &fn, bool first = false); + /** + * @brief Load shortcut file. + * + * Loads a shortcut configuration from file and sets Olive to use them. + * + * @param fn + * + * URL of the shortcut file to be loaded + * + */ + void load_shortcuts(const QString &fn); + + /** + * @brief Save shortcut file. + * + * Saves the current shortcut configuration to file. Only saves shortcuts that have been changed from default. + * + * @param fn + * + * URL to save the shortcut file to. + */ void save_shortcuts(const QString &fn); + /** + * @brief Load a CSS/QSS style from file to customize Olive's interface. + * + * @param fn + * + * URL to load the CSS file from. + */ void load_css_from_file(const QString& fn); public slots: + /** + * @brief Toggles full screen mode. + * + * Toggles the main window between full screen and windowed modes. + */ void toggle_full_screen(); signals: + /** + * @brief Signal emitted once when the main window has finished initializing + * + * Emitted the first time paintEvent runs. Connect this to functions that must be completed post-initialization. + */ void finished_first_paint(); protected: + /** + * @brief Close event + * + * Confirms whether the project can be closed, and if so performs various clean-up functions before the application + * exits. It's preferable to call clean-up functions here rather than in the destructor because this will get called + * first. + */ virtual void closeEvent(QCloseEvent *) override; - virtual void paintEvent(QPaintEvent *event) override; + + /** + * @brief Paint event + * + * Overridden to provide the finished_first_paint() signal. + */ + virtual void paintEvent(QPaintEvent *) override; private slots: + /** + * @brief Maximizes the currently hovered panel. + * + * Saves the current state of the panels/dock widgets and removes all except the currently hovered panel, + * effectively maximizing the panel to the entire window. + */ void maximize_panel(); + + /** + * @brief Reset panel layout to default. + * + * Resets the current panel layout to default. Doesn't save the current layout. + */ void reset_layout(); + /** + * @brief Function to prepare File menu. + * + * Primarily used to populate the Open Recent Projects menu. + */ void fileMenu_About_To_Be_Shown(); + + /** + * @brief Function to prepare Edit menu. + * + * Primarily used to set the enabled state on Undo and Redo depending if there are undos/redos available. + */ void editMenu_About_To_Be_Shown(); + + /** + * @brief Function to prepare Window menu. + * + * Primarily used to set the checked state of menu items corresponding to the panels that are currently visible. + */ void windowMenu_About_To_Be_Shown(); + + /** + * @brief Function to prepare Playback menu. + * + * Primarily used to set the checked state on the "Loop" item. + */ void playbackMenu_About_To_Be_Shown(); + + /** + * @brief Function to prepare View menu. + * + * Primarily used to set the checked state of various options in the view menu (e.g. title safe area, timecode + * units, etc.) + */ void viewMenu_About_To_Be_Shown(); + + /** + * @brief Function to prepare Tools menu. + * + * Primarily used to set the checked state on various settings available from the Tools menu. + */ void toolMenu_About_To_Be_Shown(); + /** + * @brief Toggle whether a panel is visible or not. + * + * Assumes the sender() QAction has a pointer to a QDockWidget in its data variable. Casts it and toggles its + * visibility. + */ void toggle_panel_visibility(); private: + /** + * @brief Internal function for setting the panel layout to a predetermined preset. + * + * Resets layout to default and optionally loads a layout from file. If loading from file, this function will + * always load from `get_config_path() + "/layout"`. + * + * @param reset + * + * **TRUE** if this function should just reset the current layout. **FALSE** if it should load from the + * aforementioned layout file. + */ void setup_layout(bool reset); + + /** + * @brief Initialize menu bar menus and items. + * + * Internal initialization function for all menus and menu items in the main window. Called once from the + * MainWindow() constructor. + */ void setup_menus(); // menu bar menus diff --git a/oliveglobal.cpp b/oliveglobal.cpp index 3536b05cc..2a1036b39 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -115,8 +115,7 @@ void OliveGlobal::open_project() { } } -void OliveGlobal::open_recent() { - int index = static_cast(sender())->data().toInt(); +void OliveGlobal::open_recent(int index) { QString recent_url = recent_projects.at(index); if (!QFile::exists(recent_url)) { if (QMessageBox::question( diff --git a/oliveglobal.h b/oliveglobal.h index b18d59275..5349f3d64 100644 --- a/oliveglobal.h +++ b/oliveglobal.h @@ -6,21 +6,86 @@ #include #include +/** + * @brief The Olive Global class + * + * A resource for various global functions used throughout Olive. + */ class OliveGlobal : public QObject { Q_OBJECT public: + /** + * @brief OliveGlobal Constructor + * + * Creates Olive Global object. Also sets some default runtime settings and the application name. + */ OliveGlobal(); + /** + * @brief Returns the file dialog filter used when interfacing with Olive project files. + * + * @return The file filter string used by QFileDialog to limit the files shown to Olive (*.ove) files. + */ const QString& get_project_file_filter(); + /** + * @brief Change the current active project filename + * + * Triggered to change the current active project filename. Call this before calling any internal project + * saving or loading functions in order to set which file to work with (OliveGlobal::open_project() and + * OliveGlobal::save_project_as() do this automatically). Also updates the main window title to reflect the + * project filename. + * + * @param s + * + * The URL of the project file to work with. Can be an empty string, in which case Olive will treat the project + * as an unsaved project. + */ void update_project_filename(const QString& s); + /** + * @brief Check whether an auto-recovery file exists and ask the user if they want to load it. + * + * Usually called on initialization. Checks if an auto-recovery file exists (meaning the last session of Olive + * didn't close correctly). If it finds one, asks the user if they want to load it. If so, loads the auto-recovery + * project. + */ void check_for_autorecovery_file(); + /** + * @brief Set the application state depending on if the user is exporting a video + * + * Some background functions shouldn't run while Olive is exporting a video. This function will disable/enable them + * as necessary. + * + * The current functions are as follows: + * * Auto-recovery interval. Olive saves an auto-recovery just before exporting anyway and seeing as the user + * cannot make changes while rendering, there's no reason to continue saving auto-recovery files. + * * Audio device playback. Olive uses the same internal audio buffer for exporting as it does for playback, but + * this buffer does not need to be forwarded to the output device when exporting. + * + * @param rendering + * + * **TRUE** if Olive is about to export a video. **FALSE** if Olive has finished exporting. + */ void set_rendering_state(bool rendering); + /** + * @brief Set a project to load just after launching + * + * Called by main() if Olive was called with a project file as a running argument. Sets up Olive to load the + * specified project once its finished initializing. + * + * @param s + * + * The URL of the project file to load. + */ void load_project_on_launch(const QString& s); + /** + * @brief Retrieves the URL of the config file containing the autorecovery projects + * @return The URL as a string + */ QString get_recent_project_list_file(); public slots: @@ -53,21 +118,101 @@ public slots: */ void paste_insert(); - + /** + * @brief Create new project. + * + * Confirms whether the current project can be closed, and if so, clears all current project data and resets + * program state. Standard `File > New` behavior. + */ void new_project(); + + /** + * @brief Open a project from file. + * + * Confirms whether the current project can be closed, and if so, shows an open file dialog to allow the user to + * select a project file and then triggers a project load with it. + */ void open_project(); - void open_recent(); + + /** + * @brief Open recent project from list + * + * Triggers a project load from the internal recent projects list. + * + * @param index + * + * Index in the list of the project fille to load + */ + void open_recent(int index); + + /** + * @brief Shows a save file dialog and saves the project as the resulting filename + * + * Shows a save file dialog for the user to save their current project as a different filename from the current + * one. Also triggered by save_project() if the file hasn't been saved yet. + * + * @return **TRUE** if the user saved the project. **FALSE** if they cancelled out of the save file dialog. Useful + * if a user is closing an unsaved project, clicks "Yes" to save, we know if they actually saved or not and won't + * continue closing the project if they didn't. + */ bool save_project_as(); + + /** + * @brief Saves the current project to file + * + * If the project has been saved already, this function will overwrite the project file with the current project + * data. Calls save_project_as() if the file has not been saved before. + * + * @return **TRUE** if the project has been saved before and was successfully overwritten. Otherwise returns the + * value of save_project_as(). Useful if the user closing an unsaved project, clicks "Yes" to save, we know if they + * actually saved or not and won't continue closing the project if they didn't. + */ bool save_project(); + /** + * @brief Determine whether the current project can be closed. + * + * Queried any time the current project is going to be closed (e.g. starting a new project, loading a project, + * exiting Olive, etc.) If the project has unsaved changes, this function asks the user whether they want to save or + * not. If the user does, calls save_project() (which may in turn call save_project_as() if the project has never + * been saved). + * + * @return **TRUE** if the project can be closed. FALSE if not. If the project does NOT have unsaved changes, always + * returns **TRUE**. If it does and the user clicks YES, this returns the result of save_project(). If the user + * clicks NO, this returns **TRUE**. If the user clicks CANCEL, this returns **FALSE**. + */ bool can_close_project(); + /** + * @brief Open the Export dialog to trigger an export of the current sequence. + */ void open_export_dialog(); + + /** + * @brief Open the About Olive dialog. + */ void open_about_dialog(); + + /** + * @brief Open the Debug Log window. + */ void open_debug_log(); + + /** + * @brief Open the Speed/Duration dialog. + */ void open_speed_dialog(); + + /** + * @brief Open the Action Search overlay. + */ void open_action_search(); + /** + * @brief Clears the current undo stack. + * + * Clears all current commands in the undo stack. Mostly used for debugging. + */ void clear_undo_stack(); /** diff --git a/ui/focusfilter.cpp b/ui/focusfilter.cpp index bc903de67..b3286a607 100644 --- a/ui/focusfilter.cpp +++ b/ui/focusfilter.cpp @@ -6,10 +6,7 @@ FocusFilter Olive::FocusFilter; -FocusFilter::FocusFilter() -{ - -} +FocusFilter::FocusFilter() {} void FocusFilter::go_to_in() { QDockWidget* focused_panel = get_focused_panel(); diff --git a/ui/focusfilter.h b/ui/focusfilter.h index b560c9178..9c780622e 100644 --- a/ui/focusfilter.h +++ b/ui/focusfilter.h @@ -3,43 +3,204 @@ #include +/** + * @brief The FocusFilter class + * + * Some keyboard shortcuts/menu actions will do different things depending on the panel that's currently focused. + * For example, pressing "Set Marker" will set a marker on the main active sequence if the timeline is focused, + * or on the media in the Media Viewer if the Media Viewer is focused. This class provides slots/functions that + * can be called that will check which panel is focused and call the appropriate function. + * + * Responds to `config.hover_focus`. Default behavior is focus by clicking on the panels, but if `hover_focus` is + * **TRUE**, the focused panel will be whichever panel has the cursor currently hovering over it. + */ class FocusFilter : public QObject { Q_OBJECT public: + /** + * @brief FocusFilter Constructor + * + * Currently empty. + */ FocusFilter(); public slots: + /** + * @brief Cuts selected clips or selected effects (but not both). + * + * If the Effect Controls panel is focused, cuts selected effects. Otherwise cuts selected clips. + */ void cut(); + + /** + * @brief Copies selected clips or selected effects (but not both). + * + * If the Effect Controls panel is focused, copies selected effects. Otherwise copies selected clips. + */ void copy(); + /** + * @brief Duplicates currently selected items + * + * Currently this only duplicates Sequences in the project panel. + */ void duplicate(); + /** + * @brief Go to In Point. + * + * Calls go_to_in() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void go_to_in(); + + /** + * @brief Go to Out Point. + * + * Calls go_to_out() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void go_to_out(); + + /** + * @brief Go to Start + * + * Calls go_to_start() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void go_to_start(); + + /** + * @brief Go to Previous Frame + * + * Calls previous_frame() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void prev_frame(); + + /** + * @brief Play In Point to Out Point + * + * Calls play(true) on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void play_in_to_out(); + + /** + * @brief Toggle Play/Pause + * + * Calls toggle_play() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void playpause(); + + /** + * @brief Pause/Shuttle Stop. + * + * Calls pause() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void pause(); + + /** + * @brief Increase Speed/Shuttle Right + * + * Calls increase_speed() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void increase_speed(); + + /** + * @brief Decrease Speed/Shuttle Left + * + * Calls decrease_speed() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void decrease_speed(); + + /** + * @brief Go to Next Frame + * + * Calls next_frame() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void next_frame(); + + /** + * @brief Go to End + * + * Calls go_to_end() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void go_to_end(); + /** + * @brief Set currently focused viewer to full screen + * + * Calls viewer_widget->set_fullscreen() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void set_viewer_fullscreen(); + /** + * @brief Set a marker at the current playhead + * + * Calls set_marker() on Media Viewer or Sequence Viewer if it's focused. Otherwise calls it on Timeline. + */ void set_marker(); + /** + * @brief Set in point + * + * Calls set_in_point() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void set_in_point(); + + /** + * @brief Set out point + * + * Calls set_out_point() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void set_out_point(); + + /** + * @brief Clear in point + * + * Calls clear_in() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void clear_in(); + + /** + * @brief Clear out point + * + * Calls clear_out() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void clear_out(); + + /** + * @brief Clear in/out point + * + * Calls clear_inout() on Media Viewer it's focused. Otherwise calls it on Sequence Viewer. + */ void clear_inout(); + /** + * @brief Delete + * + * Calls various delete functions based on which UI elements are focused. Deletes span anywhere from deleting + * clips (Timeline), to effects (Effect Controls), to markers (TimelineHeader). + */ void delete_function(); + + /** + * @brief Select All + * + * Calls select_all() on Graph Editor if its focused or Timeline if it's not. + */ void select_all(); + /** + * @brief Zoom In + * + * Calls zoom_in() on Effect Controls, Footage Viewer, or Sequence Viewer if one of them is focused. Otherwise + * calls it on Timeline. + */ void zoom_in(); + + /** + * @brief Zoom Out + * + * Calls zoom_out() on Effect Controls, Footage Viewer, or Sequence Viewer if one of them is focused. Otherwise + * calls it on Timeline. + */ void zoom_out(); }; diff --git a/ui/menuhelper.cpp b/ui/menuhelper.cpp index ca145baf5..b2f03f438 100644 --- a/ui/menuhelper.cpp +++ b/ui/menuhelper.cpp @@ -146,3 +146,8 @@ void MenuHelper::set_timecode_view() { config.timecode_view = action->data().toInt(); update_ui(false); } + +void MenuHelper::open_recent_from_menu() { + int index = static_cast(sender())->data().toInt(); + Olive::Global.data()->open_recent(index); +} diff --git a/ui/menuhelper.h b/ui/menuhelper.h index 31273909e..4d904d394 100644 --- a/ui/menuhelper.h +++ b/ui/menuhelper.h @@ -55,20 +55,102 @@ public: */ void make_edit_functions_menu(QMenu* parent); + /** + * @brief Sets the checked state of a menu item based on a Boolean variable. + * + * Many menu items simply toggle a Boolean variable. This is a convenience function, assuming the QAction's data + * variable is a pointer to a Boolean variable, that sets the checked state of the QAction to the enabled state + * of the Boolean. Used heavily in functions like toolMenu_About_To_Be_Shown() + * + * @param a + * + * The QAction to set the checked state of. + */ void set_bool_action_checked(QAction* a); + + /** + * @brief Sets the checked state of a menu item based on an integer variable. + * + * Many menu items simply set a variable to a particular integer. This is a convenience function, assuming the + * QAction's data variable is an integer to set a variable to, that sets the checked state of the QAction to + * whether the QAction's integer equals the integer variable. Used heavily in functions like + * viewMenu_About_To_Be_Shown() + * + * @param a + * + * The QAction to set the checked state of + * + * @param i + * + * The integer variable to compare the QAction's integer to + */ void set_int_action_checked(QAction* a, const int& i); + + /** + * @brief Sets the checked state of a menu item based on a QPushButton. + * + * Some menu items function largely as a proxy to a QPushButton. Assuming the QAction's data variable is a + * pointer to a QPushButton, this sets a QAction's checked state to the checked state of the QPushButton. + * + * @param a + */ void set_button_action_checked(QAction* a); public slots: + /** + * @brief Sets a QAction's Boolean reference to the opposite of its current value + * + * Many menu items simply toggle a Boolean variable. This is a convenience function, assuming the QAction's data + * variable is a pointer to a Boolean variable, that sets the Boolean variable to the opposite of its current value. + */ void toggle_bool_action(); + /** + * @brief Set Title/Action Safe Area from QAction + * + * A receiver for several Title/Action Safe Area setting items. Assumes the sender() is a QAction with a data + * variable as a `double`. The `double` can be the following values: + * * NaN (qSNaN()) - Disable Title/Action Safe Area + * * 0 - Enable Title/Action Safe Area, default aspect ratio (match current active Sequence's aspect ratio). + * * Negative Value - Enable Title/Action Safe Area, any negative number assumes a custom aspect ratio. Will ask + * the user to enter an aspect ratio and will use the result. + * * Positive Value - Enable Title/Action Safe Area, use value as the aspect ratio. + */ void set_titlesafe_from_menu(); + /** + * @brief Set Autoscroll setting from QAction + * + * Assumes the sender() is a QAction with an integer as its data variable. The data variable should be + * `AUTOSCROLL_NO_SCROLL`, `AUTOSCROLL_PAGE_SCROLL` (default) or `AUTOSCROLL_SMOOTH_SCROLL`. + */ void set_autoscroll(); + + /** + * @brief Clicks a QPushButton referenced by a QAction when triggered. + * + * Some menu items function largely as a proxy to a QPushButton. Assuming the QAction's data variable is a + * pointer to a QPushButton, this triggers a click() event on that QPushButton. + */ void menu_click_button(); + + /** + * @brief Sets the current timecode setting + * + * Assumes the sender() is a QAction with an integer as its data variable. The data variable should be + * `AUTOSCROLL_NO_AUTOSCROLL`, `AUTOSCROLL_PAGE_AUTOSCROLL` (default) or `AUTOSCROLL_SMOOTH_AUTOSCROLL`. + */ void set_timecode_view(); + /** + * @brief Calls open_recent() in Olive::Global using the index from a QAction + * + * Assumes the sender() is a QAction with an integer as its data variable. The data variable is an index of + * the internal auto-recovery project list. + */ + void open_recent_from_menu(); + private slots: