Commit 5325726a authored by Aurélien Bertron's avatar Aurélien Bertron Committed by Jean-Baptiste Mardelle

Add whole hierarchy when adding folder

Fix #240
parent 18a58684
......@@ -1146,21 +1146,17 @@ void Bin::createClip(const QDomElement &xml)
parentFolder->appendChild(newClip);
}
QString Bin::slotAddFolder(const QString &folderName)
void Bin::slotAddFolder()
{
auto parentFolder = m_itemModel->getFolderByBinId(getCurrentFolder());
qDebug() << "pranteforder id" << parentFolder->clipId();
QString newId;
Fun undo = []() { return true; };
Fun redo = []() { return true; };
m_itemModel->requestAddFolder(newId, folderName.isEmpty() ? i18n("Folder") : folderName, parentFolder->clipId(), undo, redo);
m_itemModel->requestAddFolder(newId, i18n("Folder"), parentFolder->clipId(), undo, redo);
pCore->pushUndo(undo, redo, i18n("Create bin folder"));
// Edit folder name
if (!folderName.isEmpty()) {
// We already have a name, no need to edit
return newId;
}
auto folder = m_itemModel->getFolderByBinId(newId);
auto ix = m_itemModel->getIndexFromItem(folder);
qDebug() << "selecting" << ix;
......@@ -1176,7 +1172,6 @@ QString Bin::slotAddFolder(const QString &folderName)
}
m_itemView->edit(m_proxyModel->mapFromSource(ix));
}
return newId;
}
QModelIndex Bin::getIndexForId(const QString &id, bool folderWanted) const
......@@ -1669,6 +1664,24 @@ void Bin::doRefreshPanel(const QString &id)
}
}
QAction *Bin::addAction(const QString &name, const QString &text, const QIcon &icon)
{
auto *action = new QAction(text, this);
if (!icon.isNull()) {
action->setIcon(icon);
}
pCore->window()->addAction(name, action);
return action;
}
void Bin::setupAddClipAction(QMenu *addClipMenu, ClipType::ProducerType type, const QString &name, const QString &text, const QIcon &icon)
{
QAction *action = addAction(name, text, icon);
action->setData(static_cast<QVariant>(type));
addClipMenu->addAction(action);
connect(action, &QAction::triggered, this, &Bin::slotCreateProjectClip);
}
void Bin::showClipProperties(const std::shared_ptr<ProjectClip> &clip, bool forceRefresh)
{
if ((clip == nullptr) || !clip->isReady()) {
......@@ -1879,35 +1892,91 @@ void Bin::setupGeneratorMenu()
m_menu->insertSeparator(m_deleteAction);
}
void Bin::setupMenu(QMenu *addMenu, QAction *defaultAction, const QHash<QString, QAction *> &actions)
{
void Bin::setupMenu()
{
auto *addClipMenu = new QMenu(this);
QAction *addClip =
addAction(QStringLiteral("add_clip"), i18n("Add Clip or Folder"), QIcon::fromTheme(QStringLiteral("kdenlive-add-clip")));
addClipMenu->addAction(addClip);
connect(addClip, &QAction::triggered, this, &Bin::slotAddClip);
setupAddClipAction(addClipMenu, ClipType::Color, QStringLiteral("add_color_clip"), i18n("Add Color Clip"), QIcon::fromTheme(QStringLiteral("kdenlive-add-color-clip")));
setupAddClipAction(addClipMenu, ClipType::SlideShow, QStringLiteral("add_slide_clip"), i18n("Add Slideshow Clip"), QIcon::fromTheme(QStringLiteral("kdenlive-add-slide-clip")));
setupAddClipAction(addClipMenu, ClipType::Text, QStringLiteral("add_text_clip"), i18n("Add Title Clip"), QIcon::fromTheme(QStringLiteral("kdenlive-add-text-clip")));
setupAddClipAction(addClipMenu, ClipType::TextTemplate, QStringLiteral("add_text_template_clip"), i18n("Add Template Title"), QIcon::fromTheme(QStringLiteral("kdenlive-add-text-clip")));
QAction *downloadResourceAction =
addAction(QStringLiteral("download_resource"), i18n("Online Resources"), QIcon::fromTheme(QStringLiteral("edit-download")));
addClipMenu->addAction(downloadResourceAction);
connect(downloadResourceAction, &QAction::triggered, pCore->window(), &MainWindow::slotDownloadResources);
m_locateAction =
addAction(QStringLiteral("locate_clip"), i18n("Locate Clip..."), QIcon::fromTheme(QStringLiteral("edit-file")));
m_locateAction->setData("locate_clip");
m_locateAction->setEnabled(false);
connect(m_locateAction, &QAction::triggered, this, &Bin::slotLocateClip);
m_reloadAction =
addAction(QStringLiteral("reload_clip"), i18n("Reload Clip"), QIcon::fromTheme(QStringLiteral("view-refresh")));
m_reloadAction->setData("reload_clip");
m_reloadAction->setEnabled(false);
connect(m_reloadAction, &QAction::triggered, this, &Bin::slotReloadClip);
m_duplicateAction =
addAction(QStringLiteral("duplicate_clip"), i18n("Duplicate Clip"), QIcon::fromTheme(QStringLiteral("edit-copy")));
m_duplicateAction->setData("duplicate_clip");
m_duplicateAction->setEnabled(false);
connect(m_duplicateAction, &QAction::triggered, this, &Bin::slotDuplicateClip);
m_proxyAction = new QAction(i18n("Proxy Clip"), pCore->window());
pCore->window()->addAction(QStringLiteral("proxy_clip"), m_proxyAction);
m_proxyAction->setData(QStringList() << QString::number(static_cast<int>(AbstractClipJob::PROXYJOB)));
m_proxyAction->setCheckable(true);
m_proxyAction->setChecked(false);
m_editAction =
addAction(QStringLiteral("clip_properties"), i18n("Clip Properties"), QIcon::fromTheme(QStringLiteral("document-edit")));
m_editAction->setData("clip_properties");
connect(m_editAction, &QAction::triggered, this, static_cast<void (Bin::*)()>(&Bin::slotSwitchClipProperties));
m_openAction =
addAction(QStringLiteral("edit_clip"), i18n("Edit Clip"), QIcon::fromTheme(QStringLiteral("document-open")));
m_openAction->setData("edit_clip");
m_openAction->setEnabled(false);
connect(m_openAction, &QAction::triggered, this, &Bin::slotOpenClip);
m_renameAction =
addAction(QStringLiteral("rename_clip"), i18n("Rename Clip"), QIcon::fromTheme(QStringLiteral("document-edit")));
m_renameAction->setData("rename_clip");
m_renameAction->setEnabled(false);
connect(m_renameAction, &QAction::triggered, this, &Bin::slotRenameItem);
m_deleteAction =
addAction(QStringLiteral("delete_clip"), i18n("Delete Clip"), QIcon::fromTheme(QStringLiteral("edit-delete")));
m_deleteAction->setData("delete_clip");
m_deleteAction->setEnabled(false);
connect(m_deleteAction, &QAction::triggered, this, &Bin::slotDeleteClip);
QAction *createFolder =
addAction(QStringLiteral("create_folder"), i18n("Create Folder"), QIcon::fromTheme(QStringLiteral("folder-new")));
connect(createFolder, &QAction::triggered, this, &Bin::slotAddFolder);
// Setup actions
QAction *first = m_toolbar->actions().at(0);
m_deleteAction = actions.value(QStringLiteral("delete"));
m_toolbar->insertAction(first, m_deleteAction);
QAction *folder = actions.value(QStringLiteral("folder"));
m_toolbar->insertAction(m_deleteAction, folder);
m_editAction = actions.value(QStringLiteral("properties"));
m_openAction = actions.value(QStringLiteral("open"));
m_reloadAction = actions.value(QStringLiteral("reload"));
m_duplicateAction = actions.value(QStringLiteral("duplicate"));
m_locateAction = actions.value(QStringLiteral("locate"));
m_proxyAction = actions.value(QStringLiteral("proxy"));
m_renameAction = actions.value(QStringLiteral("rename"));
m_toolbar->insertAction(m_deleteAction, createFolder);
auto *m = new QMenu(this);
m->addActions(addMenu->actions());
m->addActions(addClipMenu->actions());
m_addButton = new QToolButton(this);
m_addButton->setMenu(m);
m_addButton->setDefaultAction(defaultAction);
m_addButton->setDefaultAction(addClip);
m_addButton->setPopupMode(QToolButton::MenuButtonPopup);
m_toolbar->insertWidget(folder, m_addButton);
m_toolbar->insertWidget(createFolder, m_addButton);
m_menu = new QMenu(this);
m_propertiesDock = pCore->window()->addDock(i18n("Clip Properties"), QStringLiteral("clip_properties"), m_propertiesPanel);
m_propertiesDock->close();
// m_menu->addActions(addMenu->actions());
}
const QString Bin::getDocumentProperty(const QString &key)
......
......@@ -198,7 +198,7 @@ public:
/** @brief Current producer has changed, refresh monitor and timeline*/
void refreshClip(const QString &id);
void setupMenu(QMenu *addMenu, QAction *defaultAction, const QHash<QString, QAction *> &actions);
void setupMenu();
/** @brief The source file was modified, we will reload it soon, disable item in the meantime */
void setWaitingStatus(const QString &id);
......@@ -322,7 +322,7 @@ public slots:
void slotSwitchClipProperties(const std::shared_ptr<ProjectClip> &clip);
void slotSwitchClipProperties();
/** @brief Creates a new folder with optional name, and returns new folder's id */
QString slotAddFolder(const QString &folderName = QString());
void slotAddFolder();
void slotCreateProjectClip();
void slotEditClipCommand(const QString &id, const QMap<QString, QString> &oldProps, const QMap<QString, QString> &newProps);
/** @brief Start a filter job requested by a filter applied in timeline */
......@@ -432,6 +432,8 @@ private:
long m_processedAudio;
/** @brief Indicates whether audio thumbnail creation is running. */
QFuture<void> m_audioThumbsThread;
QAction *addAction(const QString &name, const QString &text, const QIcon &icon);
void setupAddClipAction(QMenu *addClipMenu, ClipType::ProducerType type, const QString &name, const QString &text, const QIcon &icon);
void showClipProperties(const std::shared_ptr<ProjectClip> &clip, bool forceRefresh = false);
/** @brief Get the QModelIndex value for an item in the Bin. */
QModelIndex getIndexForId(const QString &id, bool folderWanted) const;
......
......@@ -235,6 +235,13 @@ bool ClipCreator::createClipsFromList(const QList<QUrl> &list, bool checkRemovab
if (mType.inherits(QLatin1String("inode/directory"))) {
// user dropped a folder, import its files
QDir dir(file.path());
QString folderId;
Fun local_undo = []() { return true; };
Fun local_redo = []() { return true; };
bool folderCreated = pCore->projectItemModel()->requestAddFolder(folderId, dir.dirName(), parentFolder, local_undo, local_redo);
if (!folderCreated) {
continue;
}
QStringList result = dir.entryList(QDir::Files);
QStringList subfolders = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
QList<QUrl> folderFiles;
......@@ -257,9 +264,6 @@ bool ClipCreator::createClipsFromList(const QList<QUrl> &list, bool checkRemovab
folderFiles.append(url);
}
}
QString folderId;
Fun local_undo = []() { return true; };
Fun local_redo = []() { return true; };
if (folderFiles.isEmpty()) {
QList<QUrl> sublist;
for (const QString &sub : subfolders) {
......@@ -270,46 +274,44 @@ bool ClipCreator::createClipsFromList(const QList<QUrl> &list, bool checkRemovab
}
if (!sublist.isEmpty()) {
// load subfolders
created = created || createClipsFromList(sublist, checkRemovable, parentFolder, model, undo, redo, false);
created = created || createClipsFromList(sublist, checkRemovable, folderId, model, undo, redo, false);
}
} else {
bool ok = pCore->projectItemModel()->requestAddFolder(folderId, dir.dirName(), parentFolder, local_undo, local_redo);
if (ok) {
ok = createClipsFromList(folderFiles, checkRemovable, folderId, model, local_undo, local_redo, false);
created = true;
if (!ok) {
local_undo();
} else {
UPDATE_UNDO_REDO_NOLOCK(local_redo, local_undo, undo, redo);
}
// Check subfolders
QList<QUrl> sublist;
for (const QString &sub : subfolders) {
QUrl url = QUrl::fromLocalFile(dir.absoluteFilePath(sub));
if (!list.contains(url)) {
sublist << url;
}
}
if (!sublist.isEmpty()) {
// load subfolders
createClipsFromList(sublist, checkRemovable, folderId, model, undo, redo, false);
bool clipsCreated = createClipsFromList(folderFiles, checkRemovable, folderId, model, local_undo, local_redo, false);
created = true;
if (!clipsCreated) {
local_undo();
} else {
UPDATE_UNDO_REDO_NOLOCK(local_redo, local_undo, undo, redo)
}
// Check subfolders
QList<QUrl> sublist;
for (const QString &sub : subfolders) {
QUrl url = QUrl::fromLocalFile(dir.absoluteFilePath(sub));
if (!list.contains(url)) {
sublist << url;
}
}
if (!sublist.isEmpty()) {
// load subfolders
createClipsFromList(sublist, checkRemovable, folderId, model, undo, redo, false);
}
}
continue;
}
if (checkRemovable && isOnRemovableDevice(file) && !isOnRemovableDevice(pCore->currentDoc()->projectDataFolder())) {
int answer = KMessageBox::warningContinueCancel(
QApplication::activeWindow(),
i18n("Clip <b>%1</b><br /> is on a removable device, will not be available when device is unplugged or mounted at a different position. You "
"may want to copy it first to your hard-drive. Would you like to add it anyways?",
file.path()),
i18n("Removable device"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QStringLiteral("confirm_removable_device"));
} else {
// file is not a directory
if (checkRemovable && isOnRemovableDevice(file) && !isOnRemovableDevice(pCore->currentDoc()->projectDataFolder())) {
int answer = KMessageBox::warningContinueCancel(
QApplication::activeWindow(),
i18n("Clip <b>%1</b><br /> is on a removable device, will not be available when device is unplugged or mounted at a different position. You "
"may want to copy it first to your hard-drive. Would you like to add it anyways?",
file.path()),
i18n("Removable device"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QStringLiteral("confirm_removable_device"));
if (answer == KMessageBox::Cancel) continue;
if (answer == KMessageBox::Cancel) continue;
}
QString id = ClipCreator::createClipFromFile(file.toLocalFile(), parentFolder, model, undo, redo);
created = created || (id != QStringLiteral("-1"));
}
QString id = ClipCreator::createClipFromFile(file.toLocalFile(), parentFolder, model, undo, redo);
created = created || (id != QStringLiteral("-1"));
}
qDebug() << "/////////// creatclipsfromlist return" << created;
return created;
......
......@@ -16,7 +16,7 @@
<Action name="add_slide_clip" />
<Action name="add_text_clip" />
<Action name="add_text_template_clip" />
<Action name="add_folder" />
<Action name="create_folder" />
<Action name="download_resource" />
<Menu name="generators" ><text>Generators</text>
</Menu>
......
......@@ -1445,83 +1445,12 @@ void MainWindow::setupActions()
redo->setEnabled(enable);
});
auto *addClips = new QMenu(this);
QAction *addClip =
addAction(QStringLiteral("add_clip"), i18n("Add Clip"), pCore->bin(), SLOT(slotAddClip()), QIcon::fromTheme(QStringLiteral("kdenlive-add-clip")));
addClips->addAction(addClip);
QAction *action = addAction(QStringLiteral("add_color_clip"), i18n("Add Color Clip"), pCore->bin(), SLOT(slotCreateProjectClip()),
QIcon::fromTheme(QStringLiteral("kdenlive-add-color-clip")));
action->setData((int)ClipType::Color);
addClips->addAction(action);
action = addAction(QStringLiteral("add_slide_clip"), i18n("Add Slideshow Clip"), pCore->bin(), SLOT(slotCreateProjectClip()),
QIcon::fromTheme(QStringLiteral("kdenlive-add-slide-clip")));
action->setData((int)ClipType::SlideShow);
addClips->addAction(action);
action = addAction(QStringLiteral("add_text_clip"), i18n("Add Title Clip"), pCore->bin(), SLOT(slotCreateProjectClip()),
QIcon::fromTheme(QStringLiteral("kdenlive-add-text-clip")));
action->setData((int)ClipType::Text);
addClips->addAction(action);
action = addAction(QStringLiteral("add_text_template_clip"), i18n("Add Template Title"), pCore->bin(), SLOT(slotCreateProjectClip()),
QIcon::fromTheme(QStringLiteral("kdenlive-add-text-clip")));
action->setData((int)ClipType::TextTemplate);
addClips->addAction(action);
/*action = addAction(QStringLiteral("add_qtext_clip"), i18n("Add Simple Text Clip"), pCore->bin(), SLOT(slotCreateProjectClip()),
QIcon::fromTheme(QStringLiteral("kdenlive-add-text-clip")));
action->setData((int) QText);
addClips->addAction(action);*/
QAction *addFolder =
addAction(QStringLiteral("add_folder"), i18n("Create Folder"), pCore->bin(), SLOT(slotAddFolder()), QIcon::fromTheme(QStringLiteral("folder-new")));
addClips->addAction(addAction(QStringLiteral("download_resource"), i18n("Online Resources"), this, SLOT(slotDownloadResources()),
QIcon::fromTheme(QStringLiteral("edit-download"))));
QAction *clipProperties = addAction(QStringLiteral("clip_properties"), i18n("Clip Properties"), pCore->bin(), SLOT(slotSwitchClipProperties()),
QIcon::fromTheme(QStringLiteral("document-edit")));
clipProperties->setData("clip_properties");
QAction *openClip =
addAction(QStringLiteral("edit_clip"), i18n("Edit Clip"), pCore->bin(), SLOT(slotOpenClip()), QIcon::fromTheme(QStringLiteral("document-open")));
openClip->setData("edit_clip");
openClip->setEnabled(false);
QAction *deleteClip =
addAction(QStringLiteral("delete_clip"), i18n("Delete Clip"), pCore->bin(), SLOT(slotDeleteClip()), QIcon::fromTheme(QStringLiteral("edit-delete")));
deleteClip->setData("delete_clip");
deleteClip->setEnabled(false);
QAction *renameClip =
addAction(QStringLiteral("rename_clip"), i18n("Rename Clip"), pCore->bin(), SLOT(slotRenameItem()), QIcon::fromTheme(QStringLiteral("document-edit")));
renameClip->setData("rename_clip");
renameClip->setEnabled(false);
QAction *reloadClip =
addAction(QStringLiteral("reload_clip"), i18n("Reload Clip"), pCore->bin(), SLOT(slotReloadClip()), QIcon::fromTheme(QStringLiteral("view-refresh")));
reloadClip->setData("reload_clip");
reloadClip->setEnabled(false);
QAction *disableEffects = addAction(QStringLiteral("disable_timeline_effects"), i18n("Disable Timeline Effects"), pCore->projectManager(),
SLOT(slotDisableTimelineEffects(bool)), QIcon::fromTheme(QStringLiteral("favorite")));
disableEffects->setData("disable_timeline_effects");
disableEffects->setCheckable(true);
disableEffects->setChecked(false);
QAction *locateClip =
addAction(QStringLiteral("locate_clip"), i18n("Locate Clip..."), pCore->bin(), SLOT(slotLocateClip()), QIcon::fromTheme(QStringLiteral("edit-file")));
locateClip->setData("locate_clip");
locateClip->setEnabled(false);
QAction *duplicateClip = addAction(QStringLiteral("duplicate_clip"), i18n("Duplicate Clip"), pCore->bin(), SLOT(slotDuplicateClip()),
QIcon::fromTheme(QStringLiteral("edit-copy")));
duplicateClip->setData("duplicate_clip");
duplicateClip->setEnabled(false);
QAction *proxyClip = new QAction(i18n("Proxy Clip"), this);
addAction(QStringLiteral("proxy_clip"), proxyClip);
proxyClip->setData(QStringList() << QString::number((int)AbstractClipJob::PROXYJOB));
proxyClip->setCheckable(true);
proxyClip->setChecked(false);
addAction(QStringLiteral("switch_track_lock"), i18n("Toggle Track Lock"), pCore->projectManager(), SLOT(slotSwitchTrackLock()), QIcon(),
Qt::SHIFT + Qt::Key_L);
addAction(QStringLiteral("switch_all_track_lock"), i18n("Toggle All Track Lock"), pCore->projectManager(), SLOT(slotSwitchAllTrackLock()), QIcon(),
......@@ -1533,17 +1462,7 @@ void MainWindow::setupActions()
addAction(QStringLiteral("add_project_note"), i18n("Add Project Note"), pCore->projectManager(), SLOT(slotAddProjectNote()),
QIcon::fromTheme(QStringLiteral("bookmark")));
QHash<QString, QAction *> actions({{QStringLiteral("locate"), locateClip},
{QStringLiteral("reload"), reloadClip},
{QStringLiteral("duplicate"), duplicateClip},
{QStringLiteral("proxy"), proxyClip},
{QStringLiteral("properties"), clipProperties},
{QStringLiteral("open"), openClip},
{QStringLiteral("rename"), renameClip},
{QStringLiteral("delete"), deleteClip},
{QStringLiteral("folder"), addFolder}});
pCore->bin()->setupMenu(addClips, addClip, actions);
pCore->bin()->setupMenu();
// Setup effects and transitions actions.
KActionCategory *transitionActions = new KActionCategory(i18n("Transitions"), actionCollection());
......
......@@ -279,6 +279,8 @@ public slots:
void slotZoomOut(bool zoomOnMouse = false);
/** @brief Enable or disable the use of timeline zone for edits. */
void slotSwitchTimelineZone(bool toggled);
/** @brief Open the online services search dialog. */
void slotDownloadResources();
private slots:
/** @brief Shows the shortcut dialog. */
......@@ -425,8 +427,6 @@ private slots:
void slotUpdateProxySettings();
/** @brief Disable proxies for this project. */
void slotDisableProxies();
/** @brief Open the online services search dialog. */
void slotDownloadResources();
/** @brief Process keyframe data sent from a clip to effect / transition stack. */
void slotProcessImportKeyframes(GraphicsRectItem type, const QString &tag, const QString &keyframes);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment