1
2
3 #include "filmstripselection.h"
4
5 // Tnz6 includes
6 #include "menubarcommandids.h"
7 #include "filmstripcommand.h"
8 #include "addfilmstripframespopup.h"
9 #include "renumberpopup.h"
10 #include "tapp.h"
11
12 // TnzTools includes
13 #include "tools/rasterselection.h"
14 #include "tools/strokeselection.h"
15 #include "tools/toolhandle.h"
16 #include "tools/tool.h"
17
18 // TnzQt includes
19 #include "toonzqt/strokesdata.h"
20 #include "toonzqt/gutil.h"
21
22 // TnzLib includes
23 #include "toonz/txshlevelhandle.h"
24 #include "toonz/tframehandle.h"
25 #include "toonz/txshlevel.h"
26 #include "toonz/txshsimplelevel.h"
27 #include "toonz/txshleveltypes.h"
28
29 // TnzCore includes
30 #include "tundo.h"
31
32 // Qt includes
33 #include <QApplication>
34 #include <QClipboard>
35
36 //-----------------------------------------------------------------------------
37
TFilmstripSelection()38 TFilmstripSelection::TFilmstripSelection()
39 : m_inbetweenRange(TFrameId(1), TFrameId(0)) {}
40
41 //-----------------------------------------------------------------------------
42
~TFilmstripSelection()43 TFilmstripSelection::~TFilmstripSelection() {}
44
45 //-----------------------------------------------------------------------------
46
enableCommands()47 void TFilmstripSelection::enableCommands() {
48 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
49 if (!sl) return;
50
51 enableCommand(this, MI_SelectAll, &TFilmstripSelection::selectAll);
52 enableCommand(this, MI_InvertSelection,
53 &TFilmstripSelection::invertSelection);
54
55 int type = sl->getType();
56 TFilePath path = sl->getPath();
57
58 bool doEnable =
59 (type == PLI_XSHLEVEL || type == TZP_XSHLEVEL || type == MESH_XSHLEVEL ||
60 (type == OVL_XSHLEVEL && path.getType() != "psd" &&
61 path.getType() != "gif" && path.getType() != "mp4" &&
62 path.getType() != "webm"));
63
64 TRasterImageP ri = (TRasterImageP)sl->getSimpleLevel()->getFrame(
65 sl->getSimpleLevel()->getFirstFid(), false);
66
67 bool isNotEditableFullColorLevel =
68 ((type == OVL_XSHLEVEL && path.getFrame() == TFrameId::NO_FRAME) ||
69 (ri && ri->isScanBW()));
70
71 if (doEnable && !isNotEditableFullColorLevel) {
72 enableCommand(this, MI_Cut, &TFilmstripSelection::cutFrames);
73 enableCommand(this, MI_Copy, &TFilmstripSelection::copyFrames);
74 enableCommand(this, MI_Paste, &TFilmstripSelection::pasteFrames);
75 enableCommand(this, MI_PasteInto, &TFilmstripSelection::pasteInto);
76 enableCommand(this, MI_Clear, &TFilmstripSelection::deleteFrames);
77 enableCommand(this, MI_Reverse, &TFilmstripSelection::reverseFrames);
78 enableCommand(this, MI_Swing, &TFilmstripSelection::swingFrames);
79 enableCommand(this, MI_Step2, &TFilmstripSelection::stepFrames, 2);
80 enableCommand(this, MI_Step3, &TFilmstripSelection::stepFrames, 3);
81 enableCommand(this, MI_Step4, &TFilmstripSelection::stepFrames, 4);
82 enableCommand(this, MI_Each2, &TFilmstripSelection::eachFrames, 2);
83 enableCommand(this, MI_Each3, &TFilmstripSelection::eachFrames, 3);
84 enableCommand(this, MI_Each4, &TFilmstripSelection::eachFrames, 4);
85 enableCommand(this, MI_Duplicate, &TFilmstripSelection::duplicateFrames);
86
87 if (type != MESH_XSHLEVEL) {
88 enableCommand(this, MI_Insert, &TFilmstripSelection::insertEmptyFrames);
89 enableCommand(this, MI_MergeFrames, &TFilmstripSelection::mergeFrames);
90
91 enableCommand(this, MI_AddFrames, &TFilmstripSelection::addFrames);
92 }
93 } else if (isNotEditableFullColorLevel)
94 enableCommand(this, MI_Copy, &TFilmstripSelection::copyFrames);
95
96 enableCommand(this, MI_ExposeResource, &TFilmstripSelection::exposeFrames);
97
98 if (doEnable && !isNotEditableFullColorLevel)
99 enableCommand(this, MI_Renumber, &TFilmstripSelection::renumberFrames);
100 }
101
102 //-----------------------------------------------------------------------------
103
isEmpty() const104 bool TFilmstripSelection::isEmpty() const { return m_selectedFrames.empty(); }
105
106 //-----------------------------------------------------------------------------
107
updateInbetweenRange()108 void TFilmstripSelection::updateInbetweenRange() {
109 // ibrange = (la prima) sequenza di almeno tre frame selezionati consecutivi
110 m_inbetweenRange = std::make_pair(TFrameId(1), TFrameId(0));
111 if (m_selectedFrames.size() < 3)
112 return; // ci vogliono almeno tre frames selezionati
113 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
114 if (sl) {
115 std::vector<TFrameId> fids;
116 sl->getFids(fids);
117 int m = (int)fids.size();
118 int i, j = -1;
119 for (i = 0; i < (int)fids.size(); i++)
120 if (isSelected(fids[i])) {
121 if (j < 0) j = i;
122 } else {
123 if (j >= 0 && i - j >= 3) break;
124 j = -1;
125 }
126 if (j >= 0 && i - j >= 3) {
127 m_inbetweenRange = std::make_pair(fids[j], fids[i - 1]);
128 }
129 }
130 }
131
132 //-----------------------------------------------------------------------------
133
select(const TFrameId & fid,bool selected)134 void TFilmstripSelection::select(const TFrameId &fid, bool selected) {
135 TApp *app = TApp::instance();
136
137 if (selected)
138 m_selectedFrames.insert(fid);
139 else
140 m_selectedFrames.erase(fid);
141
142 updateInbetweenRange();
143
144 TTool *tool = app->getCurrentTool()->getTool();
145 if (tool) tool->setSelectedFrames(m_selectedFrames);
146
147 TXshSimpleLevel *sl = app->getCurrentLevel()->getSimpleLevel();
148 bool rasterLevel = sl->getType() == TZP_XSHLEVEL ||
149 sl->getType() == OVL_XSHLEVEL ||
150 sl->getType() == TZI_XSHLEVEL;
151
152 CommandManager::instance()->enable(MI_CanvasSize, rasterLevel);
153 }
154
155 //-----------------------------------------------------------------------------
156
isSelected(const TFrameId & fid) const157 bool TFilmstripSelection::isSelected(const TFrameId &fid) const {
158 return m_selectedFrames.count(fid) > 0;
159 }
160
161 //-----------------------------------------------------------------------------
162
selectNone()163 void TFilmstripSelection::selectNone() {
164 m_selectedFrames.clear();
165 updateInbetweenRange();
166 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
167 CommandManager::instance()->enable(MI_CanvasSize, false);
168 }
169
170 //-----------------------------------------------------------------------------
171
selectAll()172 void TFilmstripSelection::selectAll() {
173 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
174 if (!sl) return;
175 std::vector<TFrameId> fids;
176 sl->getFids(fids);
177 m_selectedFrames.clear();
178 m_selectedFrames.insert(fids.begin(), fids.end());
179 updateInbetweenRange();
180 TTool *tool = TApp::instance()->getCurrentTool()->getTool();
181 tool->setSelectedFrames(m_selectedFrames);
182 bool rasterLevel = sl->getType() == TZP_XSHLEVEL ||
183 sl->getType() == OVL_XSHLEVEL ||
184 sl->getType() == TZI_XSHLEVEL;
185 CommandManager::instance()->enable(MI_CanvasSize, rasterLevel);
186 notifyView();
187 }
188
189 //-----------------------------------------------------------------------------
190
invertSelection()191 void TFilmstripSelection::invertSelection() {
192 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
193 if (!sl) return;
194 std::vector<TFrameId> fids;
195 sl->getFids(fids);
196 std::set<TFrameId> oldSelectedFrames = m_selectedFrames;
197 m_selectedFrames.clear();
198 std::vector<TFrameId>::iterator it;
199 for (it = fids.begin(); it != fids.end(); it++) {
200 if (oldSelectedFrames.find(*it) != oldSelectedFrames.end()) continue;
201 m_selectedFrames.insert(*it);
202 }
203 updateInbetweenRange();
204 TTool *tool = TApp::instance()->getCurrentTool()->getTool();
205 tool->setSelectedFrames(m_selectedFrames);
206 if (sl->getType() == TZP_XSHLEVEL || sl->getType() == OVL_XSHLEVEL ||
207 sl->getType() == TZI_XSHLEVEL)
208 CommandManager::instance()->enable(MI_CanvasSize, true);
209 notifyView();
210 }
211
212 //-----------------------------------------------------------------------------
213
addFrames()214 void TFilmstripSelection::addFrames() {
215 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
216 if (!sl) return;
217 AddFilmstripFramesPopup popup;
218 int ret = popup.exec();
219 if (ret == 0) return;
220
221 int startFrame = 1;
222 int endFrame = 1;
223 int stepFrame = 1;
224
225 popup.getParameters(startFrame, endFrame, stepFrame);
226 FilmstripCmd::addFrames(sl, startFrame, endFrame, stepFrame);
227 }
228
229 //-----------------------------------------------------------------------------
230
copyFrames()231 void TFilmstripSelection::copyFrames() {
232 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
233 if (sl) FilmstripCmd::copy(sl, m_selectedFrames);
234 }
235
236 //-----------------------------------------------------------------------------
237
cutFrames()238 void TFilmstripSelection::cutFrames() {
239 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
240 if (sl) {
241 int firstSelectedIndex = sl->fid2index(*m_selectedFrames.begin());
242 assert(firstSelectedIndex >= 0);
243 FilmstripCmd::cut(sl, m_selectedFrames);
244 selectNone();
245 TFrameId fId = (firstSelectedIndex == 0)
246 ? sl->getFirstFid()
247 : sl->getFrameId(firstSelectedIndex - 1);
248 TApp::instance()->getCurrentFrame()->setFid(fId);
249 select(fId);
250 }
251 }
252
253 //-----------------------------------------------------------------------------
254
pasteFrames()255 void TFilmstripSelection::pasteFrames() {
256 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
257 if (!sl) return;
258
259 std::set<TFrameId> fids;
260 if (m_selectedFrames.empty()) {
261 if (sl->isSubsequence()) return;
262 fids.insert(TApp::instance()->getCurrentFrame()->getFid());
263 } else
264 fids = m_selectedFrames;
265
266 FilmstripCmd::paste(sl, fids);
267 }
268
269 //-----------------------------------------------------------------------------
270
mergeFrames()271 void TFilmstripSelection::mergeFrames() {
272 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
273 if (sl) FilmstripCmd::merge(sl, m_selectedFrames);
274 }
275
276 //-----------------------------------------------------------------------------
277
pasteInto()278 void TFilmstripSelection::pasteInto() {
279 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
280 if (sl) FilmstripCmd::pasteInto(sl, m_selectedFrames);
281 }
282
283 //-----------------------------------------------------------------------------
284
deleteFrames()285 void TFilmstripSelection::deleteFrames() {
286 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
287 if (sl) FilmstripCmd::clear(sl, m_selectedFrames);
288 updateInbetweenRange();
289 }
290
291 //-----------------------------------------------------------------------------
292
insertEmptyFrames()293 void TFilmstripSelection::insertEmptyFrames() {
294 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
295 if (sl) FilmstripCmd::insert(sl, m_selectedFrames, true);
296 }
297
298 //-----------------------------------------------------------------------------
299
reverseFrames()300 void TFilmstripSelection::reverseFrames() {
301 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
302 if (sl) FilmstripCmd::reverse(sl, m_selectedFrames);
303 }
304
305 //-----------------------------------------------------------------------------
306
swingFrames()307 void TFilmstripSelection::swingFrames() {
308 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
309 if (sl) FilmstripCmd::swing(sl, m_selectedFrames);
310 }
311
312 //-----------------------------------------------------------------------------
313
stepFrames(int step)314 void TFilmstripSelection::stepFrames(int step) {
315 if (step < 2) return;
316 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
317 if (sl) FilmstripCmd::step(sl, m_selectedFrames, step);
318 updateInbetweenRange();
319 }
320
321 //-----------------------------------------------------------------------------
322
eachFrames(int each)323 void TFilmstripSelection::eachFrames(int each) {
324 if (each < 2) return;
325 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
326 if (sl) FilmstripCmd::each(sl, m_selectedFrames, each);
327 updateInbetweenRange();
328 }
329
330 //-----------------------------------------------------------------------------
331
duplicateFrames()332 void TFilmstripSelection::duplicateFrames() {
333 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
334 if (sl) FilmstripCmd::duplicate(sl, m_selectedFrames, true);
335 }
336
337 //-----------------------------------------------------------------------------
338
exposeFrames()339 void TFilmstripSelection::exposeFrames() {
340 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
341 if (sl) FilmstripCmd::moveToScene(sl, m_selectedFrames);
342 }
343
344 //-----------------------------------------------------------------------------
345
renumberFrames()346 void TFilmstripSelection::renumberFrames() {
347 TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
348 if (!sl) return;
349 if (m_selectedFrames.empty()) return;
350 TFrameId fid = *m_selectedFrames.begin();
351 RenumberPopup popup;
352 popup.setValues(fid.getNumber(), 1);
353 int ret = popup.exec();
354 if (ret != QDialog::Accepted) return;
355 int startFrame = 0, stepFrame = 0;
356 popup.getValues(startFrame, stepFrame);
357 if (startFrame < 1 || stepFrame < 1) {
358 DVGui::error(("Bad renumber values"));
359 return;
360 }
361 FilmstripCmd::renumber(sl, m_selectedFrames, startFrame, stepFrame);
362 updateInbetweenRange();
363 }
364