All Classes Namespaces Functions Variables Enumerations Properties Pages
importlayersdialog.cpp
1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
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 */
17 #include "importlayersdialog.h"
18 #include "ui_importlayersdialog.h"
19 
20 #include <QProgressDialog>
21 
22 #include "app_util.h"
23 #include "filemanager.h"
24 #include "filedialog.h"
25 #include "fileformat.h"
26 #include "layermanager.h"
27 #include "soundmanager.h"
28 #include "layer.h"
29 #include "layersound.h"
30 #include "soundclip.h"
31 
32 
33 ImportLayersDialog::ImportLayersDialog(QWidget *parent) :
34  QDialog(parent),
35  ui(new Ui::ImportLayersDialog)
36 {
37  ui->setupUi(this);
38  connect(ui->btnSelectFile, &QPushButton::clicked, this, &ImportLayersDialog::getFileName);
39  connect(ui->btnImportLayers, &QPushButton::clicked, this, &ImportLayersDialog::importLayers);
40  connect(ui->lwLayers, &QListWidget::itemSelectionChanged, this, &ImportLayersDialog::listWidgetChanged);
41  connect(ui->btnClose, &QPushButton::clicked, this, &ImportLayersDialog::cancel);
42  ui->lwLayers->setSelectionMode(QAbstractItemView::ExtendedSelection);
43  ui->btnImportLayers->setEnabled(false);
44 
45  hideQuestionMark(*this);
46 }
47 
48 ImportLayersDialog::~ImportLayersDialog()
49 {
50  delete ui;
51 }
52 
53 void ImportLayersDialog::setCore(Editor *editor)
54 {
55  mEditor = editor;
56 }
57 
58 void ImportLayersDialog::getFileName()
59 {
60  mFileName.clear();
61  ui->lwLayers->clear();
62  mFileName = FileDialog::getOpenFileName(this, FileType::ANIMATION, tr("Choose file"));
63  if (mFileName.isEmpty()) { return; }
64  getLayers();
65 }
66 
67 void ImportLayersDialog::listWidgetChanged()
68 {
69  mItemsSelected.clear();
70  for (int i = 0; i < ui->lwLayers->count(); i++)
71  if (ui->lwLayers->item(i)->isSelected())
72  mItemsSelected.append(i);
73 
74  if (!mItemsSelected.isEmpty())
75  ui->btnImportLayers->setEnabled(true);
76  else
77  ui->btnImportLayers->setEnabled(false);
78 }
79 
80 void ImportLayersDialog::importLayers()
81 {
82  Object* object = mEditor->object();
83  int currentFrame = mEditor->currentFrame();
84  Q_ASSERT(ui->lwLayers->count() == mImportObject->getLayerCount());
85 
86  for (int i = 0; i < ui->lwLayers->count(); i++ )
87  {
88  QListWidgetItem* item = ui->lwLayers->item(i);
89  if (item->isSelected())
90  {
91  int layerId = item->data(Qt::UserRole).toInt();
92 
93  mImportLayer = mImportObject->takeLayer(layerId);
94  mImportLayer->setName(mEditor->layers()->nameSuggestLayer(item->text()));
95  loadKeyFrames(mImportLayer); // all keyframes of this layer must be in memory
96 
97  object->addLayer(mImportLayer);
98 
99  if (mImportLayer->type() == Layer::SOUND)
100  {
101  LayerSound* layerSound = static_cast<LayerSound*>(mImportLayer);
102  int count = 0;
103  while (count < layerSound->getNextKeyFramePosition(count))
104  {
105  int newKeyPos = layerSound->getNextKeyFramePosition(count);
106  SoundClip* clip = new SoundClip;
107  clip = layerSound->getSoundClipWhichCovers(newKeyPos);
108  Status st = mEditor->sound()->loadSound(clip, clip->fileName());
109  count = newKeyPos;
110  }
111  }
112  }
113  }
114  mEditor->object()->modification();
115 
116  mImportObject.reset();
117  getLayers();
118  mEditor->scrubTo(currentFrame);
119 }
120 
121 void ImportLayersDialog::cancel()
122 {
123  close();
124 }
125 
126 void ImportLayersDialog::getLayers()
127 {
128  QProgressDialog progress(tr("Opening document..."), tr("Abort"), 0, 100, this);
129 
130  // Don't show progress bar if running without a GUI (aka. when rendering from command line)
131  if (isVisible())
132  {
133  hideQuestionMark(progress);
134  progress.setWindowModality(Qt::WindowModal);
135  progress.show();
136  }
137 
138  FileManager fm;
139  connect(&fm, &FileManager::progressChanged, [&progress](int p)
140  {
141  progress.setValue(p);
143  });
144  connect(&fm, &FileManager::progressRangeChanged, [&progress](int max)
145  {
146  progress.setRange(0, max + 3);
147  });
148  mImportObject.reset(fm.load(mFileName));
149 
150  ui->lwLayers->clear();
151  for (int i = 0; i < mImportObject->getLayerCount(); i++)
152  {
153  const QString layerName = mImportObject->getLayer(i)->name();
154  const int layerId = mImportObject->getLayer(i)->id();
155 
156  // Store the layer name as well as layer ID cuz two layers could have the same name
157  QListWidgetItem* item = new QListWidgetItem(layerName);
158  item->setData(Qt::UserRole, layerId);
159  ui->lwLayers->addItem(item);
160  }
161 }
162 
163 void ImportLayersDialog::loadKeyFrames(Layer* importedLayer)
164 {
165  // Pencil2D only keeps a small portion of keyframes in the memory initially
166  // Here we need to force load all the keyframes of this layer into memory
167  // Otherwise the keyframe data will lose after mImportObject is deleted
168  importedLayer->foreachKeyFrame([](KeyFrame* k)
169  {
170  k->loadFile();
171  });
172 }
void clear()
bool close()
void setupUi(QWidget *widget)
bool isSelected() const const
bool isVisible() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
void clear()
void processEvents(QEventLoop::ProcessEventsFlags flags)
void append(const T &value)
int toInt(bool *ok) const const
bool isEmpty() const const
UserRole
bool isEmpty() const const
void clicked(bool checked)
Definition: layer.h:39
virtual QVariant data(int role) const const
virtual void setData(int role, const QVariant &value)
static QString getOpenFileName(QWidget *parent, FileType fileType, const QString &caption=QString())
Shows a file dialog which allows the user to select a file to open.
Definition: filedialog.cpp:27
Definition: object.h:54
void itemSelectionChanged()
Definition: editor.h:51
WindowModal
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString text() const const