Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_file/folder_history.cc')
-rw-r--r--source/blender/editors/space_file/folder_history.cc199
1 files changed, 199 insertions, 0 deletions
diff --git a/source/blender/editors/space_file/folder_history.cc b/source/blender/editors/space_file/folder_history.cc
new file mode 100644
index 00000000000..1cb8fa279c5
--- /dev/null
+++ b/source/blender/editors/space_file/folder_history.cc
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2007 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup spfile
+ *
+ * Storage for a list of folders for history backward and forward navigation.
+ */
+
+#include <cstring>
+
+#include "BLI_listbase.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "BKE_context.h"
+
+#include "DNA_space_types.h"
+
+#include "ED_fileselect.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "file_intern.h"
+
+/* -------------------------------------------------------------------- */
+/** \name FOLDERLIST (previous/next)
+ * \{ */
+
+typedef struct FolderList {
+ struct FolderList *next, *prev;
+ char *foldername;
+} FolderList;
+
+void folderlist_popdir(struct ListBase *folderlist, char *dir)
+{
+ const char *prev_dir;
+ struct FolderList *folder;
+ folder = static_cast<FolderList *>(folderlist->last);
+
+ if (folder) {
+ /* remove the current directory */
+ MEM_freeN(folder->foldername);
+ BLI_freelinkN(folderlist, folder);
+
+ folder = static_cast<FolderList *>(folderlist->last);
+ if (folder) {
+ prev_dir = folder->foldername;
+ BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
+ }
+ }
+ /* Delete the folder next or use set-directory directly before PREVIOUS OP. */
+}
+
+void folderlist_pushdir(ListBase *folderlist, const char *dir)
+{
+ if (!dir[0]) {
+ return;
+ }
+
+ struct FolderList *folder, *previous_folder;
+ previous_folder = static_cast<FolderList *>(folderlist->last);
+
+ /* check if already exists */
+ if (previous_folder && previous_folder->foldername) {
+ if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
+ return;
+ }
+ }
+
+ /* create next folder element */
+ folder = MEM_new<FolderList>(__func__);
+ folder->foldername = BLI_strdup(dir);
+
+ /* add it to the end of the list */
+ BLI_addtail(folderlist, folder);
+}
+
+const char *folderlist_peeklastdir(ListBase *folderlist)
+{
+ struct FolderList *folder;
+
+ if (!folderlist->last) {
+ return NULL;
+ }
+
+ folder = static_cast<FolderList *>(folderlist->last);
+ return folder->foldername;
+}
+
+bool folderlist_clear_next(struct SpaceFile *sfile)
+{
+ const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ struct FolderList *folder;
+
+ /* if there is no folder_next there is nothing we can clear */
+ if (BLI_listbase_is_empty(sfile->folders_next)) {
+ return false;
+ }
+
+ /* if previous_folder, next_folder or refresh_folder operators are executed
+ * it doesn't clear folder_next */
+ folder = static_cast<FolderList *>(sfile->folders_prev->last);
+ if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) {
+ return false;
+ }
+
+ /* eventually clear flist->folders_next */
+ return true;
+}
+
+void folderlist_free(ListBase *folderlist)
+{
+ if (folderlist) {
+ LISTBASE_FOREACH (FolderList *, folder, folderlist) {
+ MEM_freeN(folder->foldername);
+ }
+ BLI_freelistN(folderlist);
+ }
+}
+
+static ListBase folderlist_duplicate(ListBase *folderlist)
+{
+ ListBase folderlistn = {NULL};
+
+ BLI_duplicatelist(&folderlistn, folderlist);
+
+ LISTBASE_FOREACH (FolderList *, folder, &folderlistn) {
+ folder->foldername = (char *)MEM_dupallocN(folder->foldername);
+ }
+ return folderlistn;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Folder-History (wraps/owns file list above)
+ * \{ */
+
+static FileFolderHistory *folder_history_find(const SpaceFile *sfile, eFileBrowse_Mode browse_mode)
+{
+ LISTBASE_FOREACH (FileFolderHistory *, history, &sfile->folder_histories) {
+ if (history->browse_mode == browse_mode) {
+ return history;
+ }
+ }
+
+ return NULL;
+}
+
+void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile)
+{
+ FileFolderHistory *history = folder_history_find(sfile, (eFileBrowse_Mode)sfile->browse_mode);
+
+ if (!history) {
+ history = MEM_cnew<FileFolderHistory>(__func__);
+ history->browse_mode = sfile->browse_mode;
+ BLI_addtail(&sfile->folder_histories, history);
+ }
+
+ sfile->folders_next = &history->folders_next;
+ sfile->folders_prev = &history->folders_prev;
+}
+
+static void folder_history_entry_free(SpaceFile *sfile, FileFolderHistory *history)
+{
+ if (sfile->folders_prev == &history->folders_prev) {
+ sfile->folders_prev = NULL;
+ }
+ if (sfile->folders_next == &history->folders_next) {
+ sfile->folders_next = NULL;
+ }
+ folderlist_free(&history->folders_prev);
+ folderlist_free(&history->folders_next);
+ BLI_freelinkN(&sfile->folder_histories, history);
+}
+
+void folder_history_list_free(SpaceFile *sfile)
+{
+ LISTBASE_FOREACH_MUTABLE (FileFolderHistory *, history, &sfile->folder_histories) {
+ folder_history_entry_free(sfile, history);
+ }
+}
+
+ListBase folder_history_list_duplicate(ListBase *listbase)
+{
+ ListBase histories = {NULL};
+
+ LISTBASE_FOREACH (FileFolderHistory *, history, listbase) {
+ FileFolderHistory *history_new = static_cast<FileFolderHistory *>(MEM_dupallocN(history));
+ history_new->folders_prev = folderlist_duplicate(&history->folders_prev);
+ history_new->folders_next = folderlist_duplicate(&history->folders_next);
+ BLI_addtail(&histories, history_new);
+ }
+
+ return histories;
+}
+
+/** \} */