1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

[FileBrowser] Add sorting-method. (#1340)

* [FileBrowser] Add sorting-method.

* [FileBrowser] Convert -file-browser-directory to new config format.
This commit is contained in:
TonCherAmi 2021-06-27 10:28:21 +03:00 committed by GitHub
parent 330402aa13
commit 0ff0866be7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 192 additions and 19 deletions

View file

@ -118,9 +118,6 @@ Settings config = {
/** Desktop Link launch command */
.drun_url_launcher = "xdg-open",
/** Directory the file browser starts in */
.file_browser_directory = NULL,
/** Window fields to match in window mode*/
.window_match_fields = "all",
/** Monitor */

View file

@ -1167,10 +1167,26 @@ Message can be multi\-line.
.SS File browser settings
.PP
\fB\fC\-filebrowser\-directory\fR \fIdirectory\fP
File browser behavior can be controlled via the following options:
.PP
Directory the file browser starts in.
.RS
.nf
configuration {
filebrowser {
/** Directory the file browser starts in. */
directory: "/some/directory";
/**
* Sorting method. Can be set to:
* - "name"
* - "mtime" (modification time)
* - "atime" (access time)
* - "ctime" (change time)
*/
sorting-method: "name";
}
}
.SS Other
.PP

View file

@ -698,9 +698,24 @@ Message can be multi-line.
### File browser settings
`-filebrowser-directory` *directory*
File browser behavior can be controlled via the following options:
Directory the file browser starts in.
```css
configuration {
filebrowser {
/** Directory the file browser starts in. */
directory: "/some/directory";
/**
* Sorting method. Can be set to:
* - "name"
* - "mtime" (modification time)
* - "atime" (access time)
* - "ctime" (change time)
*/
sorting-method: "name";
}
}
```
### Other

View file

@ -116,9 +116,6 @@ typedef struct
/** Desktop Link launch command */
char * drun_url_launcher;
/** Directory the file browser starts in */
char * file_browser_directory;
/** Search case sensitivity */
unsigned int case_sensitive;
/** Cycle through in the element list */

View file

@ -36,11 +36,11 @@
#include <dirent.h>
#include "mode.h"
#include "theme.h"
#include "helper.h"
#include "mode-private.h"
#include "dialogs/filebrowser.h"
#include "rofi.h"
#include "settings.h"
#include "history.h"
#include <stdint.h>
@ -59,6 +59,26 @@ enum FBFileType
RFILE,
NUM_FILE_TYPES,
};
/**
* Possible sorting methods
*/
enum FBSortingMethod
{
FB_SORT_NAME,
FB_SORT_TIME,
};
/**
* Type of time to sort by
*/
enum FBSortingTime
{
FB_MTIME,
FB_ATIME,
FB_CTIME,
};
/** Icons to use for the file type */
const char *icon_name[NUM_FILE_TYPES] =
{
@ -73,6 +93,7 @@ typedef struct
enum FBFileType type;
uint32_t icon_fetch_uid;
gboolean link;
time_t time;
} FBFile;
typedef struct
@ -82,6 +103,15 @@ typedef struct
unsigned int array_length;
} FileBrowserModePrivateData;
struct
{
enum FBSortingMethod sorting_method;
enum FBSortingTime sorting_time;
} file_browser_config = {
.sorting_method = FB_SORT_NAME,
.sorting_time = FB_MTIME,
};
static void free_list ( FileBrowserModePrivateData *pd )
{
for ( unsigned int i = 0; i < pd->array_length; i++ ) {
@ -96,10 +126,11 @@ static void free_list ( FileBrowserModePrivateData *pd )
#include <sys/types.h>
#include <dirent.h>
static gint compare ( gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data )
static gint compare_name ( gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data )
{
FBFile *fa = (FBFile *) a;
FBFile *fb = (FBFile *) b;
if ( fa->type != fb->type ) {
return fa->type - fb->type;
}
@ -107,7 +138,74 @@ static gint compare ( gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer d
return g_strcmp0 ( fa->name, fb->name );
}
static void get_file_browser ( Mode *sw )
static gint compare_time ( gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data )
{
FBFile *fa = (FBFile *) a;
FBFile *fb = (FBFile *) b;
if ( fa->time < 0 ) {
return -1;
}
if ( fb->time < 0 ) {
return 1;
}
return fb->time - fa->time;
}
static gint compare ( gconstpointer a, gconstpointer b, gpointer data )
{
GCompareDataFunc comparator = NULL;
switch ( file_browser_config.sorting_method )
{
case FB_SORT_NAME:
comparator = compare_name;
break;
case FB_SORT_TIME:
comparator = compare_time;
break;
default:
comparator = compare_name;
break;
}
return comparator ( a, b, data );
}
static time_t get_time ( const struct stat *statbuf )
{
switch ( file_browser_config.sorting_time )
{
case FB_MTIME:
return statbuf->st_mtim.tv_sec;
case FB_ATIME:
return statbuf->st_atim.tv_sec;
case FB_CTIME:
return statbuf->st_ctim.tv_sec;
default:
return 0;
}
}
static void set_time ( FBFile *file )
{
gchar* path = g_filename_from_utf8 ( file->path, -1, NULL, NULL, NULL );
struct stat statbuf;
if ( stat ( path, &statbuf ) == 0 ) {
file->time = get_time ( &statbuf );
}
else {
g_warning ( "Failed to stat file: %s, %s", path, strerror ( errno ) );
}
g_free ( path );
}
static void get_file_browser ( Mode *sw )
{
FileBrowserModePrivateData *pd = (FileBrowserModePrivateData *) mode_get_private_data ( sw );
/**
@ -127,6 +225,7 @@ static void get_file_browser ( Mode *sw )
pd->array[pd->array_length].type = UP;
pd->array[pd->array_length].icon_fetch_uid = 0;
pd->array[pd->array_length].link = FALSE;
pd->array[pd->array_length].time = -1;
pd->array_length++;
continue;
}
@ -152,6 +251,11 @@ static void get_file_browser ( Mode *sw )
pd->array[pd->array_length].type = ( rd->d_type == DT_DIR ) ? DIRECTORY : RFILE;
pd->array[pd->array_length].icon_fetch_uid = 0;
pd->array[pd->array_length].link = FALSE;
if ( file_browser_config.sorting_method == FB_SORT_TIME ) {
set_time ( &pd->array[pd->array_length] );
}
pd->array_length++;
break;
case DT_LNK:
@ -177,6 +281,10 @@ static void get_file_browser ( Mode *sw )
else if ( S_ISREG ( statbuf.st_mode ) ) {
pd->array[pd->array_length].type = RFILE;
}
if ( file_browser_config.sorting_method == FB_SORT_TIME ) {
pd->array[pd->array_length].time = get_time ( &statbuf );
}
}
else {
g_warning ( "Failed to stat file: %s, %s", file, strerror ( errno ) );
@ -194,14 +302,56 @@ static void get_file_browser ( Mode *sw )
g_qsort_with_data ( pd->array, pd->array_length, sizeof ( FBFile ), compare, NULL );
}
static void file_browser_mode_init_config ( Mode *sw )
{
char *msg = NULL;
gboolean found_error = FALSE;
ThemeWidget *wid = rofi_config_find_widget ( sw->name, NULL, TRUE );
Property *p = rofi_theme_find_property ( wid, P_STRING, "sorting-method", TRUE );
if ( p != NULL && p->type == P_STRING ) {
if ( g_strcmp0 ( p->value.s, "name" ) == 0 ) {
file_browser_config.sorting_method = FB_SORT_NAME;
}
else if ( g_strcmp0 ( p->value.s, "mtime" ) == 0 ) {
file_browser_config.sorting_method = FB_SORT_TIME;
file_browser_config.sorting_time = FB_MTIME;
}
else if ( g_strcmp0 ( p->value.s, "atime" ) == 0 ) {
file_browser_config.sorting_method = FB_SORT_TIME;
file_browser_config.sorting_time = FB_ATIME;
}
else if ( g_strcmp0 ( p->value.s, "ctime" ) == 0 ) {
file_browser_config.sorting_method = FB_SORT_TIME;
file_browser_config.sorting_time = FB_CTIME;
}
else {
found_error = TRUE;
msg = g_strdup_printf ( "\"%s\" is not a valid filebrowser sorting method", p->value.s );
}
}
if ( found_error ) {
rofi_view_error_dialog ( msg, FALSE );
g_free ( msg );
}
}
static void file_browser_mode_init_current_dir ( Mode *sw ) {
FileBrowserModePrivateData *pd = (FileBrowserModePrivateData *) mode_get_private_data ( sw );
gboolean config_has_valid_dir = config.file_browser_directory != NULL
&& g_file_test ( config.file_browser_directory, G_FILE_TEST_IS_DIR );
ThemeWidget *wid = rofi_config_find_widget ( sw->name, NULL, TRUE );
Property *p = rofi_theme_find_property ( wid, P_STRING, "directory", TRUE );
gboolean config_has_valid_dir = p != NULL && p->type == P_STRING
&& g_file_test ( p->value.s, G_FILE_TEST_IS_DIR );
if ( config_has_valid_dir ) {
pd->current_dir = g_file_new_for_path ( config.file_browser_directory );
pd->current_dir = g_file_new_for_path ( p->value.s );
} else {
char *current_dir = NULL;
char *cache_file = g_build_filename ( cache_dir, FILEBROWSER_CACHE_FILE, NULL );
@ -233,6 +383,7 @@ static int file_browser_mode_init ( Mode *sw )
FileBrowserModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
mode_set_private_data ( sw, (void *) pd );
file_browser_mode_init_config ( sw );
file_browser_mode_init_current_dir ( sw );
// Load content.

View file

@ -132,9 +132,6 @@ static XrmOption xrmOptions[] = {
{ xrm_String, "drun-url-launcher", { .str = &config.drun_url_launcher }, NULL,
"Command to open a Desktop Entry that is a Link.", CONFIG_DEFAULT },
{ xrm_String, "filebrowser-directory", { .str = &config.file_browser_directory }, NULL,
"Directory the file browser starts in", CONFIG_DEFAULT },
{ xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL,
"Disable history in run/ssh", CONFIG_DEFAULT },
{ xrm_String, "ignored-prefixes", { .str = &config.ignored_prefixes }, NULL,