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  layerSound->foreachKeyFrame([this](KeyFrame* key)
103  {
104  SoundClip* clip = dynamic_cast<SoundClip*>(key);
105  Status st = mEditor->sound()->loadSound(clip, clip->fileName());
106  Q_ASSERT(st.ok());
107  });
108  }
109  }
110  }
111  mEditor->object()->modification();
112 
113  mImportObject.reset();
114  getLayers();
115  mEditor->scrubTo(currentFrame);
116 }
117 
118 void ImportLayersDialog::cancel()
119 {
120  close();
121 }
122 
123 void ImportLayersDialog::getLayers()
124 {
125  QProgressDialog progress(tr("Opening document..."), tr("Abort"), 0, 100, this);
126 
127  // Don't show progress bar if running without a GUI (aka. when rendering from command line)
128  if (isVisible())
129  {
130  hideQuestionMark(progress);
131  progress.setWindowModality(Qt::WindowModal);
132  progress.show();
133  }
134 
135  FileManager fm;
136  connect(&fm, &FileManager::progressChanged, [&progress](int p)
137  {
138  progress.setValue(p);
140  });
141  connect(&fm, &FileManager::progressRangeChanged, [&progress](int max)
142  {
143  progress.setRange(0, max + 3);
144  });
145  mImportObject.reset(fm.load(mFileName));
146 
147  ui->lwLayers->clear();
148  for (int i = 0; i < mImportObject->getLayerCount(); i++)
149  {
150  const QString layerName = mImportObject->getLayer(i)->name();
151  const int layerId = mImportObject->getLayer(i)->id();
152 
153  // Store the layer name as well as layer ID cuz two layers could have the same name
154  QListWidgetItem* item = new QListWidgetItem(layerName);
155  item->setData(Qt::UserRole, layerId);
156  ui->lwLayers->addItem(item);
157  }
158 }
159 
160 void ImportLayersDialog::loadKeyFrames(Layer* importedLayer)
161 {
162  // Pencil2D only keeps a small portion of keyframes in the memory initially
163  // Here we need to force load all the keyframes of this layer into memory
164  // Otherwise the keyframe data will lose after mImportObject is deleted
165  importedLayer->foreachKeyFrame([](KeyFrame* k)
166  {
167  k->loadFile();
168  });
169 }
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:38
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:41
void itemSelectionChanged()
Definition: editor.h:55
WindowModal
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString text() const const