Cleanup: Move file browser history handing to own file
Was placed in filelist.cc, which didn't make much sense since they deal with quite different things.
This commit is contained in:
@@ -29,6 +29,7 @@ set(SRC
|
||||
file_utils.c
|
||||
filelist.cc
|
||||
filesel.c
|
||||
folder_history.cc
|
||||
fsmenu.c
|
||||
space_file.c
|
||||
|
||||
|
||||
@@ -185,6 +185,19 @@ void file_on_reload_callback_register(struct SpaceFile *sfile,
|
||||
onReloadFn callback,
|
||||
onReloadFnData custom_data);
|
||||
|
||||
/* folder_history.cc */
|
||||
|
||||
/* not listbase itself */
|
||||
void folderlist_free(struct ListBase *folderlist);
|
||||
void folderlist_popdir(struct ListBase *folderlist, char *dir);
|
||||
void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
|
||||
const char *folderlist_peeklastdir(struct ListBase *folderlist);
|
||||
int folderlist_clear_next(struct SpaceFile *sfile);
|
||||
|
||||
void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile);
|
||||
void folder_history_list_free(struct SpaceFile *sfile);
|
||||
struct ListBase folder_history_list_duplicate(struct ListBase *listbase);
|
||||
|
||||
/* file_panels.c */
|
||||
|
||||
void file_tool_props_region_panels_register(struct ARegionType *art);
|
||||
|
||||
@@ -79,173 +79,6 @@
|
||||
|
||||
#define FILEDIR_NBR_ENTRIES_UNSET -1
|
||||
|
||||
/* ----------------- 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 setdir 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;
|
||||
}
|
||||
|
||||
int 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 0;
|
||||
}
|
||||
|
||||
/* 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 0;
|
||||
}
|
||||
|
||||
/* eventually clear flist->folders_next */
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* ----------------- 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;
|
||||
}
|
||||
|
||||
/* ------------------FILELIST------------------------ */
|
||||
|
||||
struct FileListInternEntry {
|
||||
|
||||
@@ -35,17 +35,6 @@ typedef enum FileCheckType {
|
||||
CHECK_ALL = 3,
|
||||
} FileCheckType;
|
||||
|
||||
/* not listbase itself */
|
||||
void folderlist_free(struct ListBase *folderlist);
|
||||
void folderlist_popdir(struct ListBase *folderlist, char *dir);
|
||||
void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
|
||||
const char *folderlist_peeklastdir(struct ListBase *folderlist);
|
||||
int folderlist_clear_next(struct SpaceFile *sfile);
|
||||
|
||||
void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile);
|
||||
void folder_history_list_free(struct SpaceFile *sfile);
|
||||
struct ListBase folder_history_list_duplicate(struct ListBase *listbase);
|
||||
|
||||
void filelist_setsorting(struct FileList *filelist, short sort, bool invert_sort);
|
||||
void filelist_sort(struct FileList *filelist);
|
||||
|
||||
|
||||
191
source/blender/editors/space_file/folder_history.cc
Normal file
191
source/blender/editors/space_file/folder_history.cc
Normal file
@@ -0,0 +1,191 @@
|
||||
/* 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"
|
||||
|
||||
/* ----------------- 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 setdir 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;
|
||||
}
|
||||
|
||||
int 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 0;
|
||||
}
|
||||
|
||||
/* 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 0;
|
||||
}
|
||||
|
||||
/* eventually clear flist->folders_next */
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* ----------------- 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;
|
||||
}
|
||||
Reference in New Issue
Block a user