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 #ifndef TIMELINE_H
22 #define TIMELINE_H
23 
24 #include <QVector>
25 #include <QTime>
26 #include <QPushButton>
27 
28 #include "ui/timelinewidget.h"
29 #include "ui/timelinetools.h"
30 #include "timeline/selection.h"
31 #include "timeline/clip.h"
32 #include "timeline/mediaimportdata.h"
33 #include "undo/undo.h"
34 #include "ui/timelineheader.h"
35 #include "ui/resizablescrollbar.h"
36 #include "ui/audiomonitor.h"
37 #include "ui/panel.h"
38 
39 enum CreateObjects {
40   ADD_OBJ_TITLE,
41   ADD_OBJ_SOLID,
42   ADD_OBJ_BARS,
43   ADD_OBJ_TONE,
44   ADD_OBJ_NOISE,
45   ADD_OBJ_AUDIO
46 };
47 
48 enum TrimType {
49   TRIM_NONE,
50   TRIM_IN,
51   TRIM_OUT
52 };
53 
54 namespace olive {
55   namespace timeline {
56     const int kGhostThickness = 2;
57     const int kClipTextPadding = 3;
58 
59     /**
60      * @brief Set default track sizes
61      *
62      * Olive has a few default constants used for adjusting track heights in the Timeline. For HiDPI, it makes
63      * sense to multiply these by the current DPI scale. It uses a variable from QApplication to do this multiplication,
64      * which means the QApplication instance needs to be instantiated before these are calculated. Therefore, call this
65      * function ONCE after QApplication is created to multiply the track heights correctly.
66      */
67     void MultiplyTrackSizesByDPI();
68 
69     extern int kTrackDefaultHeight;
70     extern int kTrackMinHeight;
71     extern int kTrackHeightIncrement;
72   }
73 }
74 
75 int getScreenPointFromFrame(double zoom, long frame);
76 long getFrameFromScreenPoint(double zoom, int x);
77 bool selection_contains_transition(const Selection& s, Clip *c, int type);
78 void ripple_clips(ComboAction *ca, Sequence *s, long point, long length, const QVector<int>& ignore = QVector<int>());
79 
80 struct Ghost {
81   int clip;
82   long in;
83   long out;
84   int track;
85   long clip_in;
86 
87   long old_in;
88   long old_out;
89   int old_track;
90   long old_clip_in;
91 
92   // importing variables
93   Media* media;
94   int media_stream;
95 
96   // other variables
97   long ghost_length;
98   long media_length;
99   TrimType trim_type;
100 
101   // transition trimming
102   TransitionPtr transition;
103 };
104 
105 class Timeline : public Panel
106 {
107   Q_OBJECT
108 public:
109   explicit Timeline(QWidget *parent = nullptr);
110   virtual ~Timeline() override;
111 
112   bool focused();
113   void multiply_zoom(double m);
114   void copy(bool del);
115   ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame);
116   ClipPtr split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in);
117   bool split_selection(ComboAction* ca);
118   bool split_all_clips_at_point(ComboAction *ca, long point);
119   bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink);
120   void split_clip_at_positions(ComboAction* ca, int clip_index, QVector<long> positions);
121   void clean_up_selections(QVector<Selection>& areas);
122   void deselect_area(long in, long out, int track);
123   void delete_areas_and_relink(ComboAction *ca, QVector<Selection>& areas, bool deselect_areas);
124   void relink_clips_using_ids(QVector<int>& old_clips, QVector<ClipPtr>& new_clips);
125   void update_sequence();
126 
127   void edit_to_point_internal(bool in, bool ripple);
128   void delete_in_out_internal(bool ripple);
129 
130   void create_ghosts_from_media(Sequence *seq, long entry_point, QVector<olive::timeline::MediaImportData> &media_list);
131   void add_clips_from_ghosts(ComboAction *ca, Sequence *s);
132 
133   int getTimelineScreenPointFromFrame(long frame);
134   long getTimelineFrameFromScreenPoint(int x);
135   int getDisplayScreenPointFromFrame(long frame);
136   long getDisplayFrameFromScreenPoint(int x);
137 
138   int get_snap_range();
139   bool snap_to_point(long point, long* l);
140   bool snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea);
141   void set_marker();
142 
143   // shared information
144   int tool;
145   long cursor_frame;
146   int cursor_track;
147   double zoom;
148   bool zoom_just_changed;
149   long drag_frame_start;
150   int drag_track_start;
151   void update_effect_controls();
152   bool showing_all;
153   double old_zoom;
154 
155   int GetTrackHeight(int track);
156   void SetTrackHeight(int track, int height);
157 
158   // snapping
159   bool snapping;
160   bool snapped;
161   long snap_point;
162 
163   // selecting functions
164   bool selecting;
165   int selection_offset;
166   void delete_selection(QVector<Selection> &selections, bool ripple);
167   void select_all();
168   bool rect_select_init;
169   bool rect_select_proc;
170   QRect rect_select_rect;
171 
172   // moving
173   bool moving_init;
174   bool moving_proc;
175   QVector<Ghost> ghosts;
176   bool video_ghosts;
177   bool audio_ghosts;
178   bool move_insert;
179 
180   // trimming
181   int trim_target;
182   TrimType trim_type;
183   int transition_select;
184 
185   // splitting
186   bool splitting;
187   QVector<int> split_tracks;
188   QVector<int> split_cache;
189 
190   // importing
191   bool importing;
192   bool importing_files;
193 
194   // creating variables
195   bool creating;
196   int creating_object;
197 
198   // transition variables
199   bool transition_tool_init;
200   bool transition_tool_proc;
201   int transition_tool_open_clip;
202   int transition_tool_close_clip;
203   const EffectMeta* transition_tool_meta;
204   int transition_tool_side;
205 
206   // hand tool variables
207   bool hand_moving;
208   int drag_x_start;
209   int drag_y_start;
210 
211   bool block_repaints;
212 
213   TimelineHeader* headers;
214   AudioMonitor* audio_monitor;
215   ResizableScrollBar* horizontalScrollBar;
216 
217   QPushButton* toolArrowButton;
218   QPushButton* toolEditButton;
219   QPushButton* toolRippleButton;
220   QPushButton* toolRazorButton;
221   QPushButton* toolSlipButton;
222   QPushButton* toolSlideButton;
223   QPushButton* toolHandButton;
224   QPushButton* toolTransitionButton;
225   QPushButton* snappingButton;
226 
227   void scroll_to_frame(long frame);
228   void select_from_playhead();
229 
230   bool can_ripple_empty_space(long frame, int track);
231 
232   virtual void Retranslate() override;
233 protected:
234   virtual void resizeEvent(QResizeEvent *event) override;
235 public slots:
236   void paste(bool insert = false);
237   void repaint_timeline();
238   void toggle_show_all();
239   void deselect();
240   void toggle_links();
241   void split_at_playhead();
242   void ripple_delete();
243   void ripple_delete_empty_space();
244   void toggle_enable_on_selected_clips();
245 
246   void delete_inout();
247   void ripple_delete_inout();
248 
249   void ripple_to_in_point();
250   void ripple_to_out_point();
251   void edit_to_in_point();
252   void edit_to_out_point();
253 
254   void IncreaseTrackHeight();
255   void DecreaseTrackHeight();
256 
257   void previous_cut();
258   void next_cut();
259 
260   void add_transition();
261 
262   void nest();
263 
264   void zoom_in();
265   void zoom_out();
266 
267 private slots:
268   void snapping_clicked(bool checked);
269   void add_btn_click();
270   void add_menu_item(QAction*);
271   void setScroll(int);
272   void record_btn_click();
273   void transition_tool_click();
274   void transition_menu_select(QAction*);
275   void resize_move(double d);
276   void set_tool();
277 
278 private:
279   void ChangeTrackHeightUniformly(int diff);
280   void set_zoom_value(double v);
281   QVector<QPushButton*> tool_buttons;
282   void decheck_tool_buttons(QObject* sender);
283   void set_tool(int tool);
284   int scroll;
285   void set_sb_max();
286   void UpdateTitle();
287 
288   void setup_ui();
289 
290   // ripple delete empty space variables
291   long rc_ripple_min;
292   long rc_ripple_max;
293 
294   QVector<TimelineTrackHeight> track_heights;
295 
296   QWidget* timeline_area;
297   TimelineWidget* video_area;
298   TimelineWidget* audio_area;
299   QWidget* editAreas;
300   QScrollBar* videoScrollbar;
301   QScrollBar* audioScrollbar;
302   QPushButton* zoomInButton;
303   QPushButton* zoomOutButton;
304   QPushButton* recordButton;
305   QPushButton* addButton;
306   QWidget* tool_button_widget;
307 };
308 
309 #endif // TIMELINE_H
310