1 /***
2
3 Olive - Non-Linear Video Editor
4 Copyright (C) 2019 Olive Team
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 ***/
20
21 #include "menuhelper.h"
22
23 #include <QMessageBox>
24 #include <QInputDialog>
25 #include <QPushButton>
26 #include <QStyleFactory>
27
28 #include "global/config.h"
29 #include "project/clipboard.h"
30 #include "ui/mainwindow.h"
31 #include "global/global.h"
32 #include "panels/panels.h"
33 #include "ui/focusfilter.h"
34
35 MenuHelper olive::MenuHelper;
36
InitializeSharedMenus()37 void MenuHelper::InitializeSharedMenus()
38 {
39 new_project_ = create_menu_action(nullptr, "newproj", olive::Global.get(), SLOT(new_project()), QKeySequence("Ctrl+N"));
40 new_project_->setParent(this);
41
42 new_sequence_ = create_menu_action(nullptr, "newseq", panel_project, SLOT(new_sequence()), QKeySequence("Ctrl+Shift+N"));
43 new_sequence_->setParent(this);
44
45 new_folder_ = create_menu_action(nullptr, "newfolder", panel_project, SLOT(new_folder()));
46 new_folder_->setParent(this);
47
48 set_in_point_ = create_menu_action(nullptr, "setinpoint", &olive::FocusFilter, SLOT(set_in_point()), QKeySequence("I"));
49 set_in_point_->setParent(this);
50
51 set_out_point_ = create_menu_action(nullptr, "setoutpoint", &olive::FocusFilter, SLOT(set_out_point()), QKeySequence("O"));
52 set_out_point_->setParent(this);
53
54 reset_in_point_ = create_menu_action(nullptr, "resetin", &olive::FocusFilter, SLOT(clear_in()));
55 reset_in_point_->setParent(this);
56
57 reset_out_point_ = create_menu_action(nullptr, "resetout", &olive::FocusFilter, SLOT(clear_out()));
58 reset_out_point_->setParent(this);
59
60 clear_inout_point = create_menu_action(nullptr, "clearinout", &olive::FocusFilter, SLOT(clear_inout()), QKeySequence("G"));
61 clear_inout_point->setParent(this);
62
63 add_default_transition_ = create_menu_action(nullptr, "deftransition", panel_timeline, SLOT(add_transition()), QKeySequence("Ctrl+Shift+D"));
64 add_default_transition_->setParent(this);
65
66 link_unlink_ = create_menu_action(nullptr, "linkunlink", panel_timeline, SLOT(toggle_links()), QKeySequence("Ctrl+L"));
67 link_unlink_->setParent(this);
68
69 enable_disable_ = create_menu_action(nullptr, "enabledisable", panel_timeline, SLOT(toggle_enable_on_selected_clips()), QKeySequence("Shift+E"));
70 enable_disable_->setParent(this);
71
72 nest_ = create_menu_action(nullptr, "nest", panel_timeline, SLOT(nest()));
73 nest_->setParent(this);
74
75 cut_ = create_menu_action(nullptr, "cut", &olive::FocusFilter, SLOT(cut()), QKeySequence("Ctrl+X"));
76 cut_->setParent(this);
77
78 copy_ = create_menu_action(nullptr, "copy", &olive::FocusFilter, SLOT(copy()), QKeySequence("Ctrl+C"));
79 copy_->setParent(this);
80
81 paste_ = create_menu_action(nullptr, "paste", olive::Global.get(), SLOT(paste()), QKeySequence("Ctrl+V"));
82 paste_->setParent(this);
83
84 paste_insert_ = create_menu_action(nullptr, "pasteinsert", olive::Global.get(), SLOT(paste_insert()), QKeySequence("Ctrl+Shift+V"));
85 paste_insert_->setParent(this);
86
87 duplicate_ = create_menu_action(nullptr, "duplicate", &olive::FocusFilter, SLOT(duplicate()), QKeySequence("Ctrl+D"));
88 duplicate_->setParent(this);
89
90 delete_ = create_menu_action(nullptr, "delete", &olive::FocusFilter, SLOT(delete_function()), QKeySequence("Del"));
91 delete_->setParent(this);
92
93 ripple_delete_ = create_menu_action(nullptr, "rippledelete", panel_timeline, SLOT(ripple_delete()), QKeySequence("Shift+Del"));
94 ripple_delete_->setParent(this);
95
96 split_ = create_menu_action(nullptr, "split", panel_timeline, SLOT(split_at_playhead()), QKeySequence("Ctrl+K"));
97 split_->setParent(this);
98
99 Retranslate();
100 }
101
make_new_menu(QMenu * parent)102 void MenuHelper::make_new_menu(QMenu *parent) {
103 parent->addAction(new_project_);
104 parent->addSeparator();
105 parent->addAction(new_sequence_);
106 parent->addAction(new_folder_);
107 }
108
make_inout_menu(QMenu * parent)109 void MenuHelper::make_inout_menu(QMenu *parent) {
110 parent->addAction(set_in_point_);
111 parent->addAction(set_out_point_);
112 parent->addSeparator();
113 parent->addAction(reset_in_point_);
114 parent->addAction(reset_out_point_);
115 parent->addAction(clear_inout_point);
116 }
117
make_clip_functions_menu(QMenu * parent)118 void MenuHelper::make_clip_functions_menu(QMenu *parent) {
119 parent->addAction(add_default_transition_);
120 parent->addAction(link_unlink_);
121 parent->addAction(enable_disable_);
122 parent->addAction(nest_);
123 }
124
make_edit_functions_menu(QMenu * parent,bool objects_are_selected)125 void MenuHelper::make_edit_functions_menu(QMenu *parent, bool objects_are_selected) {
126 if (objects_are_selected) {
127 parent->addAction(cut_);
128 parent->addAction(copy_);
129 }
130
131 parent->addAction(paste_);
132 parent->addAction(paste_insert_);
133
134 if (objects_are_selected) {
135 parent->addAction(duplicate_);
136 parent->addAction(delete_);
137 parent->addAction(ripple_delete_);
138 parent->addAction(split_);
139 }
140 }
141
set_bool_action_checked(QAction * a)142 void MenuHelper::set_bool_action_checked(QAction *a) {
143 if (!a->data().isNull()) {
144 bool* variable = reinterpret_cast<bool*>(a->data().value<quintptr>());
145 a->setChecked(*variable);
146 }
147 }
148
set_int_action_checked(QAction * a,const int & i)149 void MenuHelper::set_int_action_checked(QAction *a, const int& i) {
150 if (!a->data().isNull()) {
151 a->setChecked(a->data() == i);
152 }
153 }
154
set_button_action_checked(QAction * a)155 void MenuHelper::set_button_action_checked(QAction *a) {
156 a->setChecked(reinterpret_cast<QPushButton*>(a->data().value<quintptr>())->isChecked());
157 }
158
Retranslate()159 void MenuHelper::Retranslate()
160 {
161 new_project_->setText(tr("&Project"));
162 new_sequence_->setText(tr("&Sequence"));
163 new_folder_->setText(tr("&Folder"));
164 set_in_point_->setText(tr("Set In Point"));
165 set_out_point_->setText(tr("Set Out Point"));
166 reset_in_point_->setText(tr("Reset In Point"));
167 reset_out_point_->setText(tr("Reset Out Point"));
168 clear_inout_point->setText(tr("Clear In/Out Point"));
169 add_default_transition_->setText(tr("Add Default Transition"));
170 link_unlink_->setText(tr("Link/Unlink"));
171 enable_disable_->setText(tr("Enable/Disable"));
172 nest_->setText(tr("Nest"));
173 cut_->setText(tr("Cu&t"));
174 copy_->setText(tr("Cop&y"));
175 paste_->setText(tr("&Paste"));
176 paste_insert_->setText(tr("Paste Insert"));
177 duplicate_->setText(tr("Duplicate"));
178 delete_->setText(tr("Delete"));
179 ripple_delete_->setText(tr("Ripple Delete"));
180 split_->setText(tr("Split"));
181 }
182
toggle_bool_action()183 void MenuHelper::toggle_bool_action() {
184 QAction* action = static_cast<QAction*>(sender());
185 bool* variable = reinterpret_cast<bool*>(action->data().value<quintptr>());
186 *variable = !(*variable);
187 update_ui(false);
188 }
189
set_titlesafe_from_menu()190 void MenuHelper::set_titlesafe_from_menu() {
191 double tsa = static_cast<QAction*>(sender())->data().toDouble();
192
193 if (qIsNaN(tsa)) {
194
195 // disable title safe area
196 olive::CurrentConfig.show_title_safe_area = false;
197
198 } else {
199
200 // using title safe area
201 olive::CurrentConfig.show_title_safe_area = true;
202
203 // are we using the default area aspect ratio, or a specific one
204 if (qIsNull(tsa)) {
205
206 // default title safe area
207 olive::CurrentConfig.use_custom_title_safe_ratio = false;
208
209 } else {
210
211 // using a specific aspect ratio
212 olive::CurrentConfig.use_custom_title_safe_ratio = true;
213
214 if (tsa < 0.0) {
215
216 // set a custom title safe area
217 QString input;
218 bool invalid = false;
219 QRegExp arTest("[0-9.]+:[0-9.]+");
220
221 do {
222 if (invalid) {
223 QMessageBox::critical(olive::MainWindow, tr("Invalid aspect ratio"), tr("The aspect ratio '%1' is invalid. Please try again.").arg(input));
224 }
225
226 input = QInputDialog::getText(olive::MainWindow, tr("Enter custom aspect ratio"), tr("Enter the aspect ratio to use for the title/action safe area (e.g. 16:9):"));
227 invalid = !arTest.exactMatch(input) && !input.isEmpty();
228 } while (invalid);
229
230 if (!input.isEmpty()) {
231 QStringList inputList = input.split(':');
232 olive::CurrentConfig.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble();
233 }
234
235 } else {
236
237 // specified tsa is a specific custom aspect ratio
238 olive::CurrentConfig.custom_title_safe_ratio = tsa;
239 }
240
241 }
242
243 }
244
245 panel_sequence_viewer->viewer_widget->update();
246 }
247
set_autoscroll()248 void MenuHelper::set_autoscroll() {
249 QAction* action = static_cast<QAction*>(sender());
250 olive::CurrentConfig.autoscroll = action->data().toInt();
251 }
252
menu_click_button()253 void MenuHelper::menu_click_button() {
254 reinterpret_cast<QPushButton*>(static_cast<QAction*>(sender())->data().value<quintptr>())->click();
255 }
256
set_timecode_view()257 void MenuHelper::set_timecode_view() {
258 QAction* action = static_cast<QAction*>(sender());
259 olive::CurrentConfig.timecode_view = action->data().toInt();
260 update_ui(false);
261 }
262
open_recent_from_menu()263 void MenuHelper::open_recent_from_menu() {
264 int index = static_cast<QAction*>(sender())->data().toInt();
265 olive::Global.get()->open_recent(index);
266 }
267
create_effect_paste_action(QMenu * menu)268 void MenuHelper::create_effect_paste_action(QMenu *menu)
269 {
270 QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool)));
271 paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT);
272 }
273
create_submenu(QMenuBar * parent,const QObject * receiver,const char * member)274 Menu* MenuHelper::create_submenu(QMenuBar* parent,
275 const QObject *receiver,
276 const char *member) {
277 Menu* menu = new Menu(parent);
278
279 /*
280 menu->setStyle(QStyleFactory::create("windowsvista"));
281 menu->setPalette(menu->style()->standardPalette());
282 menu->setStyleSheet("");
283 */
284
285 parent->addMenu(menu);
286
287 if (receiver != nullptr) {
288 QObject::connect(menu, SIGNAL(aboutToShow()), receiver, member);
289 }
290
291 return menu;
292 }
293
create_submenu(QMenu * parent)294 Menu* MenuHelper::create_submenu(QMenu* parent) {
295 Menu* menu = new Menu(parent);
296
297 /*
298 menu->setStyle(QStyleFactory::create("windowsvista"));
299 menu->setPalette(menu->style()->standardPalette());
300 menu->setStyleSheet("");
301 */
302
303 parent->addMenu(menu);
304 return menu;
305 }
306
create_menu_action(QWidget * parent,const char * id,const QObject * receiver,const char * member,const QKeySequence & shortcut)307 QAction* MenuHelper::create_menu_action(QWidget *parent,
308 const char* id,
309 const QObject *receiver,
310 const char *member,
311 const QKeySequence &shortcut) {
312 QAction* action = new QAction(parent);
313 action->setProperty("id", id);
314 action->setShortcut(shortcut);
315
316 if (receiver != nullptr) {
317 QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
318 }
319
320 if (parent != nullptr) {
321 parent->addAction(action);
322 }
323
324 return action;
325 }
326