mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -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:
parent
330402aa13
commit
0ff0866be7
6 changed files with 192 additions and 19 deletions
|
@ -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 */
|
||||
|
|
20
doc/rofi.1
20
doc/rofi.1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,6 +138,73 @@ static gint compare ( gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer d
|
|||
return g_strcmp0 ( fa->name, fb->name );
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue