more documentation and cleanup
This commit is contained in:
@@ -26,7 +26,8 @@
|
||||
/**
|
||||
* @brief The AboutDialog class
|
||||
*
|
||||
* The About dialog (accessible through Help > About). Contains license and version information.
|
||||
* The About dialog (accessible through Help > About). Contains license and version information. This can be run from
|
||||
* anywhere
|
||||
*/
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ class ActionSearchList;
|
||||
* @brief The ActionSearch class
|
||||
*
|
||||
* A popup window (accessible through Help > Action Search) that allows users to search for a menu command by typing
|
||||
* rather than browsing through the menu bar.
|
||||
* rather than browsing through the menu bar. This can be created from anywhere provided olive::MainWindow is valid.
|
||||
*/
|
||||
class ActionSearch : public QDialog
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* @brief The AdvancedVideoDialog class
|
||||
*
|
||||
* A dialog for interfacing with VideoCodecParams, a struct for more advanced video settings sometimes specific to
|
||||
* one codec.
|
||||
* one codec. Primarily a companion to ExportDialog which will provide the VideoCodecParams reference,
|
||||
*/
|
||||
class AdvancedVideoDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
/**
|
||||
* @brief The ClipPropertiesDialog class
|
||||
*
|
||||
* A dialog for setting Clip properties, accessible by right clicking a Clip and clicking "Properties".
|
||||
* A dialog for setting Clip properties, accessible by right clicking a Clip and clicking "Properties". This can be
|
||||
* run from anywhere provided it's given a valid array of Clip objects.
|
||||
*/
|
||||
class ClipPropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
/**
|
||||
* @brief The DebugDialog class
|
||||
*
|
||||
* A dialog to display the current debug output.
|
||||
* A dialog to display the current debug output. This dialog is omnipresent and shown and hidden when the user wants
|
||||
* to see it. For efficiency, it will not update if it's hidden.
|
||||
*/
|
||||
class DebugDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
@@ -69,6 +70,9 @@ private:
|
||||
};
|
||||
|
||||
namespace olive {
|
||||
/**
|
||||
* @brief Omnipresent instance of DebugDialog to be shown or hidden as the user wants
|
||||
*/
|
||||
extern DebugDialog* DebugDialog;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
/**
|
||||
* @brief The DemoNotice class
|
||||
*
|
||||
* Simple dialog shown on startup to introduce Olive as alpha software (in release builds).
|
||||
* Simple dialog shown on startup to introduce Olive as alpha software (in release builds). Can be run from anywhere,
|
||||
* but there should be no reason to create it outside of the application launch.
|
||||
*
|
||||
* To be phased out as Olive gains maturity.
|
||||
*/
|
||||
class DemoNotice : public QDialog
|
||||
{
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
/**
|
||||
* @brief The ExportDialog class
|
||||
*
|
||||
* The dialog to initiate an export.
|
||||
* The dialog to initiate an export. Requires a valid Sequence to be set in olive::ActiveSequence or the result is
|
||||
* defined (most likely a crash), so you should always do a `nullptr` check on olive::ActiveSequence before constructing
|
||||
* this dialog.
|
||||
*/
|
||||
class ExportDialog : public QDialog
|
||||
{
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
/**
|
||||
* @brief The LoadDialog class
|
||||
*
|
||||
* Shows a modal dialog for loading a project. Designed to be connected to a LoadThread object.
|
||||
* Shows a modal dialog for loading a project. Designed to be connected to a LoadThread object. This dialog should
|
||||
* generally not be created directly, use OliveGlobal::LoadProject (or its variants) to correctly set up a LoadDialog
|
||||
* and LoadThread and connect them to each other.
|
||||
*/
|
||||
class LoadDialog : public QDialog
|
||||
{
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
/**
|
||||
* @brief The MediaPropertiesDialog class
|
||||
*
|
||||
* A dialog for setting properties on Media.
|
||||
* A dialog for setting properties on Media. This can be loaded from any part of the application provided it's given
|
||||
* a valid Media object.
|
||||
*/
|
||||
class MediaPropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/**
|
||||
* @brief The NewSequenceDialog class
|
||||
*
|
||||
* A dialog that creates a new (or edits an existing) Sequence object.
|
||||
* A dialog that creates a new (or edits an existing) Sequence object. Can be run from any part of the application.
|
||||
*/
|
||||
class NewSequenceDialog : public QDialog
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ QString KeySequenceEditor::action_name() {
|
||||
QString KeySequenceEditor::export_shortcut() {
|
||||
QString ks = keySequence().toString();
|
||||
if (ks != action->property("default")) {
|
||||
return action->property("id").toString() + "\t" + keySequence().toString();
|
||||
return action->property("id").toString() + "\t" + ks;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -81,12 +81,8 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
setWindowTitle(tr("Preferences"));
|
||||
setup_ui();
|
||||
|
||||
accurateSeekButton->setChecked(!olive::CurrentConfig.fast_seeking);
|
||||
fastSeekButton->setChecked(olive::CurrentConfig.fast_seeking);
|
||||
recordingComboBox->setCurrentIndex(olive::CurrentConfig.recording_mode - 1);
|
||||
imgSeqFormatEdit->setText(olive::CurrentConfig.img_seq_formats);
|
||||
setup_ui();
|
||||
|
||||
setup_kbd_shortcuts(olive::MainWindow->menuBar());
|
||||
}
|
||||
@@ -244,7 +240,6 @@ void PreferencesDialog::accept() {
|
||||
|
||||
olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1;
|
||||
olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text();
|
||||
olive::CurrentConfig.fast_seeking = fastSeekButton->isChecked();
|
||||
olive::CurrentConfig.upcoming_queue_size = upcoming_queue_spinbox->value();
|
||||
olive::CurrentConfig.upcoming_queue_type = upcoming_queue_type->currentIndex();
|
||||
olive::CurrentConfig.previous_queue_size = previous_queue_spinbox->value();
|
||||
@@ -515,6 +510,7 @@ void PreferencesDialog::setup_ui() {
|
||||
general_layout->addWidget(new QLabel(tr("Image sequence formats:"), this), row, 0);
|
||||
|
||||
imgSeqFormatEdit = new QLineEdit(general_tab);
|
||||
imgSeqFormatEdit->setText(olive::CurrentConfig.img_seq_formats);
|
||||
|
||||
general_layout->addWidget(imgSeqFormatEdit, row, 1, 1, 4);
|
||||
|
||||
@@ -625,18 +621,6 @@ void PreferencesDialog::setup_ui() {
|
||||
QWidget* playback_tab = new QWidget(this);
|
||||
QVBoxLayout* playback_tab_layout = new QVBoxLayout(playback_tab);
|
||||
|
||||
// Playback -> Seeking
|
||||
QGroupBox* seeking_group = new QGroupBox(playback_tab);
|
||||
seeking_group->setTitle(tr("Seeking"));
|
||||
QVBoxLayout* seeking_group_layout = new QVBoxLayout(seeking_group);
|
||||
accurateSeekButton = new QRadioButton(seeking_group);
|
||||
accurateSeekButton->setText(tr("Accurate Seeking\nAlways show the correct frame (visual may pause briefly as correct frame is retrieved)"));
|
||||
seeking_group_layout->addWidget(accurateSeekButton);
|
||||
fastSeekButton = new QRadioButton(seeking_group);
|
||||
fastSeekButton->setText(tr("Fast Seeking\nSeek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export)"));
|
||||
seeking_group_layout->addWidget(fastSeekButton);
|
||||
playback_tab_layout->addWidget(seeking_group);
|
||||
|
||||
// Playback -> Memory Usage
|
||||
QGroupBox* memory_usage_group = new QGroupBox(playback_tab);
|
||||
memory_usage_group->setTitle(tr("Memory Usage"));
|
||||
@@ -739,6 +723,7 @@ void PreferencesDialog::setup_ui() {
|
||||
recordingComboBox = new QComboBox(general_tab);
|
||||
recordingComboBox->addItem(tr("Mono"));
|
||||
recordingComboBox->addItem(tr("Stereo"));
|
||||
recordingComboBox->setCurrentIndex(olive::CurrentConfig.recording_mode - 1);
|
||||
audio_tab_layout->addWidget(recordingComboBox, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
+152
-4
@@ -41,7 +41,8 @@ class KeySequenceEditor;
|
||||
/**
|
||||
* @brief The PreferencesDialog class
|
||||
*
|
||||
* A dialog for the global application settings. Mostly an interface for Config.
|
||||
* A dialog for the global application settings. Mostly an interface for Config. Can be loaded from any part of the
|
||||
* application.
|
||||
*/
|
||||
class PreferencesDialog : public QDialog
|
||||
{
|
||||
@@ -162,45 +163,192 @@ private:
|
||||
*/
|
||||
void delete_previews(char type);
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the CSS filename
|
||||
*/
|
||||
QLineEdit* custom_css_fn;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the list of extensions to detect image sequences from
|
||||
*/
|
||||
QLineEdit* imgSeqFormatEdit;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the recording channels
|
||||
*/
|
||||
QComboBox* recordingComboBox;
|
||||
QRadioButton* accurateSeekButton;
|
||||
QRadioButton* fastSeekButton;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing keyboard shortcuts
|
||||
*/
|
||||
QTreeWidget* keyboard_tree;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the upcoming queue size
|
||||
*/
|
||||
QDoubleSpinBox* upcoming_queue_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the upcoming queue type
|
||||
*/
|
||||
QComboBox* upcoming_queue_type;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the previous queue size
|
||||
*/
|
||||
QDoubleSpinBox* previous_queue_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the previous queue type
|
||||
*/
|
||||
QComboBox* previous_queue_type;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the size of textboxes in the EffectControls panel
|
||||
*/
|
||||
QSpinBox* effect_textbox_lines_field;
|
||||
|
||||
/**
|
||||
* @brief UI widget for enabling/disabling software fallbacks
|
||||
*/
|
||||
QCheckBox* use_software_fallbacks_checkbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the output audio device
|
||||
*/
|
||||
QComboBox* audio_output_devices;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the input audio device
|
||||
*/
|
||||
QComboBox* audio_input_devices;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the audio sampling rates
|
||||
*/
|
||||
QComboBox* audio_sample_rate;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the UI language
|
||||
*/
|
||||
QComboBox* language_combobox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the resolution of the thumbnails to generate
|
||||
*/
|
||||
QSpinBox* thumbnail_res_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the resolution of the waveforms to generate
|
||||
*/
|
||||
QSpinBox* waveform_res_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for enabling/disabling default effects
|
||||
*/
|
||||
QCheckBox* add_default_effects_to_clips;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the current UI style
|
||||
*/
|
||||
QComboBox* ui_style;
|
||||
Sequence sequence_settings;
|
||||
#ifdef Q_OS_WIN
|
||||
/**
|
||||
* @brief UI widget for forcing native menu styling on Windows
|
||||
*/
|
||||
QCheckBox* native_menus;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut actions that can be triggered (links with key_shortcut_items and
|
||||
* key_shortcut_fields)
|
||||
*/
|
||||
QVector<QAction*> key_shortcut_actions;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut items in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<QTreeWidgetItem*> key_shortcut_items;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut editing fields in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<KeySequenceEditor*> key_shortcut_fields;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The KeySequenceEditor class
|
||||
*
|
||||
* Simple derived class of QKeySequenceEdit that attaches to a QAction and provides functions for transferring
|
||||
* keyboard shortcuts to and from it.
|
||||
*/
|
||||
class KeySequenceEditor : public QKeySequenceEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief KeySequenceEditor Constructor
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* QWidget parent.
|
||||
*
|
||||
* @param a
|
||||
*
|
||||
* The QAction to link to. This cannot be changed throughout the lifetime of a KeySequenceEditor.
|
||||
*/
|
||||
KeySequenceEditor(QWidget *parent, QAction* a);
|
||||
|
||||
/**
|
||||
* @brief Sets the attached QAction's shortcut to the shortcut entered in this field.
|
||||
*
|
||||
* This is not done automatically in case the user cancels out of the Preferences dialog, in which case the
|
||||
* expectation is that the changes made will not be saved. Therefore, this needs to be triggered manually when
|
||||
* PreferencesDialog saves.
|
||||
*/
|
||||
void set_action_shortcut();
|
||||
|
||||
/**
|
||||
* @brief Set this shortcut back to the QAction's default shortcut
|
||||
*
|
||||
* Each QAction contains the default shortcut in its `property("default")` and can be used to restore the default
|
||||
* "hard-coded" shortcut with this function.
|
||||
*
|
||||
* This function does not save the default shortcut back into the QAction, it simply loads the default shortcut from
|
||||
* the QAction into this edit field. To save it into the QAction, it's necessary to call set_action_shortcut() after
|
||||
* calling this function.
|
||||
*/
|
||||
void reset_to_default();
|
||||
|
||||
/**
|
||||
* @brief Return attached QAction's unique ID
|
||||
*
|
||||
* Each of Olive's menu actions has a unique string ID (that, unlike the text, is not translated) for matching with
|
||||
* an external shortcut configuration file. The ID is stored in the QAction's `property("id")`. This function returns
|
||||
* that ID.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The QAction's unique ID.
|
||||
*/
|
||||
QString action_name();
|
||||
|
||||
/**
|
||||
* @brief Serialize this shortcut entry into a string that can be saved to a file
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A string serialization of this shortcut. The format is "[ID]\t[SEQUENCE]" where [ID] is the attached QAction's
|
||||
* unique identifier and [SEQUENCE] is the current keyboard shortcut in the field (NOT necessarily the shortcut in
|
||||
* the QAction). If the entered shortcut is the same as the QAction's default shortcut, the return value is empty
|
||||
* because a default shortcut does not need to be saved to a file.
|
||||
*/
|
||||
QString export_shortcut();
|
||||
private:
|
||||
/**
|
||||
* @brief Internal reference to the linked QAction
|
||||
*/
|
||||
QAction* action;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
/**
|
||||
* @brief The ProxyDialog class
|
||||
*
|
||||
* Dialog to set up proxy generation of footage
|
||||
* Dialog to set up proxy generation of footage. This dialog can be called from anywhere provided it's given a valid
|
||||
* array of Media and will start all proxy generation.
|
||||
*/
|
||||
class ProxyDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -50,16 +50,16 @@ ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, Media* old_media
|
||||
use_same_media_in_points->setChecked(true);
|
||||
layout->addWidget(use_same_media_in_points);
|
||||
|
||||
QHBoxLayout* buttons = new QHBoxLayout();
|
||||
QHBoxLayout* buttons = new QHBoxLayout();
|
||||
|
||||
buttons->addStretch();
|
||||
|
||||
QPushButton* replace_button = new QPushButton(tr("Replace"), this);
|
||||
connect(replace_button, SIGNAL(clicked(bool)), this, SLOT(replace()));
|
||||
connect(replace_button, SIGNAL(clicked(bool)), this, SLOT(accept()));
|
||||
buttons->addWidget(replace_button);
|
||||
|
||||
QPushButton* cancel_button = new QPushButton(tr("Cancel"), this);
|
||||
connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(close()));
|
||||
connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(reject()));
|
||||
buttons->addWidget(cancel_button);
|
||||
|
||||
buttons->addStretch();
|
||||
@@ -69,7 +69,7 @@ ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, Media* old_media
|
||||
tree->setModel(&olive::project_model);
|
||||
}
|
||||
|
||||
void ReplaceClipMediaDialog::replace() {
|
||||
void ReplaceClipMediaDialog::accept() {
|
||||
QModelIndexList selected_items = tree->selectionModel()->selectedRows();
|
||||
if (selected_items.size() != 1) {
|
||||
QMessageBox::critical(
|
||||
@@ -77,23 +77,23 @@ void ReplaceClipMediaDialog::replace() {
|
||||
tr("No media selected"),
|
||||
tr("Please select a media to replace with or click 'Cancel'."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
);
|
||||
} else {
|
||||
Media* new_item = static_cast<Media*>(selected_items.at(0).internalPointer());
|
||||
Media* new_item = static_cast<Media*>(selected_items.at(0).internalPointer());
|
||||
if (media == new_item) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Same media selected"),
|
||||
tr("You selected the same media that you're replacing. Please select a different one or click 'Cancel'."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
);
|
||||
} else if (new_item->get_type() == MEDIA_TYPE_FOLDER) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Folder selected"),
|
||||
tr("You cannot replace footage with a folder."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
);
|
||||
} else {
|
||||
if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == new_item->to_sequence()) {
|
||||
QMessageBox::critical(
|
||||
@@ -101,16 +101,16 @@ void ReplaceClipMediaDialog::replace() {
|
||||
tr("Active sequence selected"),
|
||||
tr("You cannot insert a sequence into itself."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
);
|
||||
} else {
|
||||
ReplaceClipMediaCommand* rcmc = new ReplaceClipMediaCommand(
|
||||
media,
|
||||
new_item,
|
||||
use_same_media_in_points->isChecked()
|
||||
);
|
||||
);
|
||||
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(i);
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(i);
|
||||
if (c != nullptr && c->media() == media) {
|
||||
rcmc->clips.append(c);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ void ReplaceClipMediaDialog::replace() {
|
||||
|
||||
olive::UndoStack.push(rcmc);
|
||||
|
||||
close();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,16 +28,55 @@
|
||||
#include "ui/sourcetable.h"
|
||||
#include "project/projectelements.h"
|
||||
|
||||
/**
|
||||
* @brief The ReplaceClipMediaDialog class
|
||||
*
|
||||
* A dialog to replace all Clips using a certain Media with a different Media. This dialog can be run from anywhere
|
||||
* provided it's given a valid Media object.
|
||||
*/
|
||||
class ReplaceClipMediaDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
ReplaceClipMediaDialog(QWidget* parent, Media* old_media);
|
||||
/**
|
||||
* @brief ReplaceClipMediaDialog Constructor
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* QWidget parent. Usually MainWindow or Project panel.
|
||||
*
|
||||
* @param old_media
|
||||
*
|
||||
* A valid Media object which will be used to scan the currently active Sequence for Clips using it.
|
||||
*/
|
||||
ReplaceClipMediaDialog(QWidget* parent, Media* old_media);
|
||||
private slots:
|
||||
void replace();
|
||||
/**
|
||||
* @brief Overrided accept for when the user clicks "Replace"
|
||||
*
|
||||
* Checks whether the requested replace is valid using the following criteria:
|
||||
* * Any Media is selected
|
||||
* * The selected Media is not the same Media that the user is trying to replace
|
||||
* * The Media is not a folder
|
||||
* * The Media is not the currently active Sequence
|
||||
*/
|
||||
virtual void accept() override;
|
||||
private:
|
||||
Media* media;
|
||||
QTreeView* tree;
|
||||
QCheckBox* use_same_media_in_points;
|
||||
/**
|
||||
* @brief Internal pointer to the Media we're replacing
|
||||
*/
|
||||
Media* media;
|
||||
|
||||
/**
|
||||
* @brief Tree widget to show Project's media
|
||||
*/
|
||||
QTreeView* tree;
|
||||
|
||||
/**
|
||||
* @brief CheckBox for using the same media in points
|
||||
*
|
||||
* When the starting point of a Clip is trimmed (i.e. the Clip no longer starts at 0),
|
||||
*/
|
||||
QCheckBox* use_same_media_in_points;
|
||||
};
|
||||
|
||||
#endif // REPLACECLIPMEDIADIALOG_H
|
||||
|
||||
@@ -85,16 +85,16 @@ SpeedDialog::SpeedDialog(QWidget *parent, QVector<Clip*> clips) : QDialog(parent
|
||||
connect(duration, SIGNAL(valueChanged(double)), this, SLOT(duration_update()));
|
||||
}
|
||||
|
||||
void SpeedDialog::run() {
|
||||
int SpeedDialog::exec() {
|
||||
bool enable_frame_rate = false;
|
||||
bool multiple_audio = false;
|
||||
maintain_pitch->setEnabled(false);
|
||||
|
||||
default_frame_rate = qSNaN();
|
||||
current_frame_rate = qSNaN();
|
||||
current_percent = qSNaN();
|
||||
default_length = -1;
|
||||
current_length = -1;
|
||||
double default_frame_rate = qSNaN();
|
||||
double current_frame_rate = qSNaN();
|
||||
double current_percent = qSNaN();
|
||||
long default_length = -1;
|
||||
long current_length = -1;
|
||||
|
||||
for (int i=0;i<clips_.size();i++) {
|
||||
Clip* c = clips_.at(i);
|
||||
@@ -180,7 +180,7 @@ void SpeedDialog::run() {
|
||||
duration->SetDefault(default_length);
|
||||
duration->SetValue((current_length == -1) ? qSNaN() : current_length);
|
||||
|
||||
exec();
|
||||
return QDialog::exec();
|
||||
}
|
||||
|
||||
void SpeedDialog::percent_update() {
|
||||
|
||||
+82
-10
@@ -27,34 +27,106 @@
|
||||
#include "timeline/clip.h"
|
||||
#include "ui/labelslider.h"
|
||||
|
||||
/**
|
||||
* @brief The SpeedDialog class
|
||||
*
|
||||
* A dialog for setting the speed of one or more Clips. This can be run from anywhere provided it's given a valid
|
||||
* array of Clips.
|
||||
*
|
||||
* It's preferable ot
|
||||
*/
|
||||
class SpeedDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief SpeedDialog Constructor
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* QWidget parent. Usually MainWindow or Timeline panel.
|
||||
*
|
||||
* @param clips
|
||||
*
|
||||
* A valid array of Clips to change the speed of.
|
||||
*/
|
||||
SpeedDialog(QWidget* parent, QVector<Clip*> clips);
|
||||
|
||||
void run();
|
||||
public slots:
|
||||
/**
|
||||
* @brief Override of exec() to set up current Clip speed data just before opening
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The result of QDialog::exec(), a DialogCode result.
|
||||
*/
|
||||
virtual int exec() override;
|
||||
private slots:
|
||||
/**
|
||||
* @brief Override of accept() to perform the selected changes on the Clips
|
||||
*/
|
||||
virtual void accept() override;
|
||||
|
||||
/**
|
||||
* @brief Slot when the speed percentage field is changed by the user
|
||||
*
|
||||
* The three fields (percent, duration, and frame rate) all work in tandem to create a speed multipler for the
|
||||
* Clip. Each has a slot for when one of the fields changes to update the others appropriately so they all have the
|
||||
* same speed multipler.
|
||||
*/
|
||||
void percent_update();
|
||||
|
||||
/**
|
||||
* @brief Slot when the duration field is changed by the user
|
||||
*
|
||||
* The three fields (percent, duration, and frame rate) all work in tandem to create a speed multipler for the
|
||||
* Clip. Each has a slot for when one of the fields changes to update the others appropriately so they all have the
|
||||
* same speed multipler.
|
||||
*/
|
||||
void duration_update();
|
||||
|
||||
/**
|
||||
* @brief Slot when the frame rate field is changed by the user
|
||||
*
|
||||
* The three fields (percent, duration, and frame rate) all work in tandem to create a speed multipler for the
|
||||
* Clip. Each has a slot for when one of the fields changes to update the others appropriately so they all have the
|
||||
* same speed multipler.
|
||||
*/
|
||||
void frame_rate_update();
|
||||
void accept();
|
||||
private:
|
||||
/**
|
||||
* @brief Internal array of Clip objects
|
||||
*/
|
||||
QVector<Clip*> clips_;
|
||||
|
||||
/**
|
||||
* @brief Speed percentage field
|
||||
*/
|
||||
LabelSlider* percent;
|
||||
|
||||
/**
|
||||
* @brief Duration field
|
||||
*/
|
||||
LabelSlider* duration;
|
||||
|
||||
/**
|
||||
* @brief Frame rate field
|
||||
*/
|
||||
LabelSlider* frame_rate;
|
||||
|
||||
/**
|
||||
* @brief UI widget for setting the Clip's reverse value
|
||||
*/
|
||||
QCheckBox* reverse;
|
||||
QCheckBox* maintain_pitch;
|
||||
QCheckBox* ripple;
|
||||
|
||||
double default_frame_rate;
|
||||
double current_frame_rate;
|
||||
double current_percent;
|
||||
long default_length;
|
||||
long current_length;
|
||||
/**
|
||||
* @brief UI widget for setting the Clip's maintain pitch value
|
||||
*/
|
||||
QCheckBox* maintain_pitch;
|
||||
|
||||
/**
|
||||
* @brief UI widget for setting whether to ripple Clips around these changes or not
|
||||
*/
|
||||
QCheckBox* ripple;
|
||||
};
|
||||
|
||||
#endif // SPEEDDIALOG_H
|
||||
|
||||
@@ -44,15 +44,6 @@ TextEditDialog::TextEditDialog(QWidget *parent, const QString &s, bool rich_text
|
||||
if (rich_text) {
|
||||
QHBoxLayout* toolbar = new QHBoxLayout();
|
||||
|
||||
// Bold Button
|
||||
/*
|
||||
bold_button = new QPushButton();
|
||||
bold_button->setIcon(olive::icon::CreateIconFromSVG(":/icons/bold.svg", false));
|
||||
bold_button->setCheckable(true);
|
||||
connect(bold_button, SIGNAL(clicked(bool)), this, SLOT(SetBold(bool)));
|
||||
toolbar->addWidget(bold_button);
|
||||
*/
|
||||
|
||||
// Italic Button
|
||||
italic_button = new QPushButton();
|
||||
italic_button->setIcon(olive::icon::CreateIconFromSVG(":/icons/italic.svg", false));
|
||||
@@ -156,10 +147,14 @@ TextEditDialog::TextEditDialog(QWidget *parent, const QString &s, bool rich_text
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
buttons->setCenterButtons(true);
|
||||
layout->addWidget(buttons);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(save()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(cancel()));
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
// Connect the cursor position changing to the rich text toolbar buttons updating (so for example, when italic text
|
||||
// is selected, the italic button will be pressed)
|
||||
connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(UpdateUIFromTextCursor()));
|
||||
|
||||
// Set the widget's text based on the rich text mode
|
||||
if (rich_text_) {
|
||||
textEdit->setHtml(s);
|
||||
} else {
|
||||
@@ -167,7 +162,7 @@ TextEditDialog::TextEditDialog(QWidget *parent, const QString &s, bool rich_text
|
||||
}
|
||||
|
||||
// Helps ensure the UI elements update correctly at the beginning - when the cursor is at the start, the UI elements
|
||||
// show up blank...
|
||||
// show up blank. Setting it to the end is probably more expected behavior anyway.
|
||||
textEdit->moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
@@ -175,21 +170,9 @@ const QString& TextEditDialog::get_string() {
|
||||
return result_str;
|
||||
}
|
||||
|
||||
void TextEditDialog::save() {
|
||||
void TextEditDialog::accept() {
|
||||
result_str = rich_text_ ? textEdit->toHtml() : textEdit->toPlainText();
|
||||
accept();
|
||||
}
|
||||
|
||||
void TextEditDialog::cancel() {
|
||||
reject();
|
||||
}
|
||||
|
||||
void TextEditDialog::SetBold(bool bold)
|
||||
{
|
||||
QFont f = textEdit->currentFont();
|
||||
f.setBold(bold);
|
||||
textEdit->setCurrentFont(f);
|
||||
UpdateUIFromTextCursor();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void TextEditDialog::SetFontWeight(int i)
|
||||
@@ -197,13 +180,6 @@ void TextEditDialog::SetFontWeight(int i)
|
||||
textEdit->setFontWeight(font_weight->itemData(i).toInt());
|
||||
}
|
||||
|
||||
void TextEditDialog::SetLetterSpacing(qreal spacing)
|
||||
{
|
||||
QFont f = textEdit->currentFont();
|
||||
f.setLetterSpacing(f.letterSpacingType(), spacing);
|
||||
textEdit->setCurrentFont(f);
|
||||
}
|
||||
|
||||
void TextEditDialog::SetAlignmentFromProperty()
|
||||
{
|
||||
textEdit->setAlignment(static_cast<Qt::Alignment>(sender()->property("a").toInt()));
|
||||
|
||||
+123
-8
@@ -28,36 +28,151 @@
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/colorbutton.h"
|
||||
|
||||
/**
|
||||
* @brief The TextEditDialog class
|
||||
*
|
||||
* A separate window for editing text. This window can be resized arbitrarily and also provides a toolbar for rich text
|
||||
* editing (if rich text is enabled). This dialog can be run from anywhere. Once the dialog has closed (i.e. returned
|
||||
* from exec() ), the text entered into it can be retrieved using get_string().
|
||||
*
|
||||
* TODO: Add a live signal for updating the calling function.
|
||||
*/
|
||||
class TextEditDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief TextEditDialog Constructor
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* QWidget parent. Usually MainWindow.
|
||||
*
|
||||
* @param s
|
||||
*
|
||||
* The starting string when the dialog opens. It'll be read as rich text HTML or plain text based on the `rich_text`
|
||||
* parameter (which defaults to rich text HTML). It can also be left empty to start blank.
|
||||
*
|
||||
* @param rich_text
|
||||
*
|
||||
* Set the editing mode of the editor. If TRUE, the dialog will interpret the string in `s` as rich text HTML and also
|
||||
* return rich text HTML through get_string(). It'll also show a toolbar with rich text options (i.e. font, italic,
|
||||
* underline, size, etc.) If FALSE, the dialog will run in plain text mode interpreting the string in `s` as plain
|
||||
* text and returning plain text through get_string(). It also will not show the rich text editing toolbar.
|
||||
*/
|
||||
TextEditDialog(QWidget* parent = nullptr, const QString& s = nullptr, bool rich_text = true);
|
||||
const QString& get_string();
|
||||
signals:
|
||||
void cursorPositionChanged();
|
||||
private slots:
|
||||
void save();
|
||||
void cancel();
|
||||
|
||||
void SetBold(bool bold);
|
||||
/**
|
||||
* @brief Retrieve the current text in the dialog
|
||||
*
|
||||
* This function can be called after the user has accepted the dialog (i.e. made changes and clicked OK).
|
||||
* This will return either plain text or rich text (HTML) depending on the mode it's running in (rich/plain text mode
|
||||
* is set in the constructor). The value this returns only gets updated when the user clicks OK so it cannot be
|
||||
* used to retrieve live text updates from the dialog.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The text entered once the user accepted this dialog.
|
||||
*/
|
||||
const QString& get_string();
|
||||
private slots:
|
||||
/**
|
||||
* @brief Override of accept() to store the entered text string so it can be retrieved by get_string().
|
||||
*/
|
||||
virtual void accept() override;
|
||||
|
||||
/**
|
||||
* @brief Slot for the font_weight combobox to set the font weight based on its data value
|
||||
*
|
||||
* @param i
|
||||
*
|
||||
* Index of the font_weight to retrieve the desired font weight from
|
||||
*/
|
||||
void SetFontWeight(int i);
|
||||
void SetLetterSpacing(qreal spacing);
|
||||
|
||||
/**
|
||||
* @brief Slot for text alignment buttons to set alignment based on their properties
|
||||
*
|
||||
* Intended slot for left_align_button, center_align_button, right_align_button, and justify_align_button. Pulls
|
||||
* from their property("a") value which should be a member of the Qt::Alignment enum.
|
||||
*/
|
||||
void SetAlignmentFromProperty();
|
||||
|
||||
/**
|
||||
* @brief Slot for when the text edit widget's cursor moves so the rich text toolbar can stay up to date
|
||||
*
|
||||
* In rich text mode, different parts of a text document can be formatted in different ways. As the user moves
|
||||
* around the text, the UI buttons should be consistent with whatever text is currently selected. This slot should
|
||||
* therefore be connected to QTextEdit::cursorPositionChanged() and will change the "checked" state of the formatting
|
||||
* buttons and current index of the comboboxes to match the currently selected text.
|
||||
*/
|
||||
void UpdateUIFromTextCursor();
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Internal rich text mode value
|
||||
*
|
||||
* This is set in the constructor and cannot be changed during the lifetime of this dialog.
|
||||
*/
|
||||
bool rich_text_;
|
||||
|
||||
/**
|
||||
* @brief Internal storage of text entered, saved when the user clicks OK
|
||||
*/
|
||||
QString result_str;
|
||||
|
||||
/**
|
||||
* @brief Main text editing widget
|
||||
*/
|
||||
QTextEdit* textEdit;
|
||||
|
||||
/**
|
||||
* @brief Toggle button for setting the italic state of the currently selected text
|
||||
*/
|
||||
QPushButton* italic_button;
|
||||
|
||||
/**
|
||||
* @brief Toggle button for setting the underlined state of the currently selected text
|
||||
*/
|
||||
QPushButton* underline_button;
|
||||
|
||||
/**
|
||||
* @brief ComboBox for the list of font families that the selected text can be set to
|
||||
*/
|
||||
QFontComboBox* font_list;
|
||||
|
||||
/**
|
||||
* @brief ComboBox for the list of font weights that the selected text can be set to
|
||||
*/
|
||||
QComboBox* font_weight;
|
||||
|
||||
/**
|
||||
* @brief A slider to set the current font size
|
||||
*/
|
||||
LabelSlider* font_size;
|
||||
|
||||
/**
|
||||
* @brief A color selector for setting the current text color
|
||||
*/
|
||||
ColorButton* font_color;
|
||||
|
||||
/**
|
||||
* @brief Button for setting the current text row(s) to left alignment
|
||||
*/
|
||||
QPushButton* left_align_button;
|
||||
|
||||
/**
|
||||
* @brief Button for setting the current text row(s) to center alignment
|
||||
*/
|
||||
QPushButton* center_align_button;
|
||||
|
||||
/**
|
||||
* @brief Button for setting the current text row(s) to right alignment
|
||||
*/
|
||||
QPushButton* right_align_button;
|
||||
|
||||
/**
|
||||
* @brief Button for setting the current text row(s) to justified alignment
|
||||
*/
|
||||
QPushButton* justify_align_button;
|
||||
};
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ Config::Config()
|
||||
drop_on_media_to_replace(true),
|
||||
autoscroll(olive::AUTOSCROLL_PAGE_SCROLL),
|
||||
audio_rate(48000),
|
||||
fast_seeking(false),
|
||||
hover_focus(false),
|
||||
project_view_type(olive::PROJECT_VIEW_TREE),
|
||||
set_name_with_marker(true),
|
||||
@@ -150,9 +149,6 @@ void Config::load(QString path) {
|
||||
} else if (stream.name() == "AudioRate") {
|
||||
stream.readNext();
|
||||
audio_rate = stream.text().toInt();
|
||||
} else if (stream.name() == "FastSeeking") {
|
||||
stream.readNext();
|
||||
fast_seeking = (stream.text() == "1");
|
||||
} else if (stream.name() == "HoverFocus") {
|
||||
stream.readNext();
|
||||
hover_focus = (stream.text() == "1");
|
||||
@@ -265,7 +261,6 @@ void Config::save(QString path) {
|
||||
stream.writeTextElement("DropFileOnMediaToReplace", QString::number(drop_on_media_to_replace));
|
||||
stream.writeTextElement("Autoscroll", QString::number(autoscroll));
|
||||
stream.writeTextElement("AudioRate", QString::number(audio_rate));
|
||||
stream.writeTextElement("FastSeeking", QString::number(fast_seeking));
|
||||
stream.writeTextElement("HoverFocus", QString::number(hover_focus));
|
||||
stream.writeTextElement("ProjectViewType", QString::number(project_view_type));
|
||||
stream.writeTextElement("SetNameWithMarker", QString::number(set_name_with_marker));
|
||||
|
||||
@@ -317,16 +317,6 @@ struct Config {
|
||||
*/
|
||||
int audio_rate;
|
||||
|
||||
/**
|
||||
* @brief Enable fast seeking
|
||||
*
|
||||
* Olive supports a seek mode that shows frames faster with the risk of briefly showing a "best-effort" frame that
|
||||
* may not be the accurate frame at that point of the Timeline. This does not affect exporting.
|
||||
*
|
||||
* Set to **TRUE** if this mode should be enabled.
|
||||
*/
|
||||
bool fast_seeking;
|
||||
|
||||
/**
|
||||
* @brief Enable hover focus
|
||||
*
|
||||
|
||||
+2
-2
@@ -76,8 +76,8 @@ void olive::icon::Initialize()
|
||||
Diamond = CreateIconFromSVG(":/icons/diamond.svg", false);
|
||||
Clock = CreateIconFromSVG(":/icons/clock.svg", false);
|
||||
|
||||
MediaVideo = CreateIconFromSVG(":/icons/videosource.svg", false);
|
||||
MediaAudio = CreateIconFromSVG(":/icons/audiosource.svg", false);
|
||||
MediaVideo = CreateIconFromSVG(":/icons/videosource.svg");
|
||||
MediaAudio = CreateIconFromSVG(":/icons/audiosource.svg");
|
||||
MediaImage = CreateIconFromSVG(":/icons/imagesource.svg", false);
|
||||
MediaError = CreateIconFromSVG(":/icons/error.svg", false);
|
||||
MediaSequence = CreateIconFromSVG(":/icons/sequence.svg", false);
|
||||
|
||||
Reference in New Issue
Block a user