diff options
| -rw-r--r-- | src/main.c | 3 | ||||
| -rw-r--r-- | src/settings.c | 18 | ||||
| -rw-r--r-- | src/settings.h | 15 | ||||
| -rw-r--r-- | src/ui.c | 73 | ||||
| -rw-r--r-- | src/ui.h | 4 | ||||
| -rw-r--r-- | src/ui_act.c | 8 | 
6 files changed, 103 insertions, 18 deletions
| @@ -175,7 +175,8 @@ int main (int argc, char **argv) {  	}  	/* no autostart? ask the user */  	if (curStation == NULL) { -		curStation = BarUiSelectStation (&ph, "Select station: ", stdin); +		curStation = BarUiSelectStation (&ph, "Select station: ", +				settings.sortOrder, stdin);  	}  	if (curStation != NULL) {  		BarUiPrintStation (curStation); diff --git a/src/settings.c b/src/settings.c index 1dee0ea..8aa764c 100644 --- a/src/settings.c +++ b/src/settings.c @@ -87,7 +87,6 @@ void BarSettingsDestroy (BarSettings_t *settings) {  void BarSettingsRead (BarSettings_t *settings) {  	/* FIXME: what is the max length of a path? */  	char configfile[1024], key[256], val[256]; -	size_t i;  	FILE *configfd;  	/* _must_ have same order as in BarKeyShortcutId_t */  	const char defaultKeys[] = {'?', '+', '-', 'a', 'c', 'd', 'e', 'g', @@ -113,6 +112,7 @@ void BarSettingsRead (BarSettings_t *settings) {  		#endif  	#endif  	settings->history = 5; +	settings->sortOrder = BAR_SORT_NAME_AZ;  	memcpy (settings->keys, defaultKeys, sizeof (defaultKeys));  	BarGetXdgConfigDir (PACKAGE "/config", configfile, sizeof (configfile)); @@ -138,6 +138,7 @@ void BarSettingsRead (BarSettings_t *settings) {  		} else if (strcmp ("password", key) == 0) {  			settings->password = strdup (val);  		} else if (memcmp ("act_", key, 4) == 0) { +			size_t i;  			/* keyboard shortcuts */  			for (i = 0; i < BAR_KS_COUNT; i++) {  				if (strcmp (shortcutFileKeys[i], key) == 0) { @@ -159,6 +160,21 @@ void BarSettingsRead (BarSettings_t *settings) {  			settings->eventCmd = strdup (val);  		} else if (strcmp ("history", key) == 0) {  			settings->history = atoi (val); +		} else if (strcmp ("sort", key) == 0) { +			size_t i; +			char *mapping[] = {"name_az", +					"name_za", +					"quickmix_01_name_az", +					"quickmix_01_name_za", +					"quickmix_10_name_az", +					"quickmix_10_name_za", +					}; +			for (i = 0; i < BAR_SORT_COUNT; i++) { +				if (strcmp (mapping[i], val) == 0) { +					settings->sortOrder = i; +					break; +				} +			}  		}  	} diff --git a/src/settings.h b/src/settings.h index 42443d7..2505321 100644 --- a/src/settings.h +++ b/src/settings.h @@ -64,16 +64,27 @@ typedef enum {  	BAR_KS_COUNT = 22,  } BarKeyShortcutId_t; +typedef enum { +	BAR_SORT_NAME_AZ = 0, +	BAR_SORT_NAME_ZA = 1, +	BAR_SORT_QUICKMIX_01_NAME_AZ = 2, +	BAR_SORT_QUICKMIX_01_NAME_ZA = 3, +	BAR_SORT_QUICKMIX_10_NAME_AZ = 4, +	BAR_SORT_QUICKMIX_10_NAME_ZA = 5, +	BAR_SORT_COUNT = 6, +} BarStationSorting_t; +  typedef struct { +	unsigned int history; +	BarStationSorting_t sortOrder; +	PianoAudioFormat_t audioFormat;  	char *username;  	char *password;  	char *controlProxy; /* non-american listeners need this */  	char *proxy;  	char keys[BAR_KS_COUNT]; -	PianoAudioFormat_t audioFormat;  	char *autostartStation;  	char *eventCmd; -	unsigned int history;  } BarSettings_t;  typedef void (*BarKeyShortcutFunc_t) (BAR_KS_ARGS); @@ -33,6 +33,7 @@ THE SOFTWARE.  #include <string.h>  #include <errno.h>  #include <strings.h> +#include <assert.h>  /* waitpid () */  #include <sys/types.h> @@ -41,6 +42,8 @@ THE SOFTWARE.  #include "ui.h"  #include "ui_readline.h" +typedef int (*BarSortFunc_t) (const void *, const void *); +  /*	output message and flush stdout   *	@param message   */ @@ -169,26 +172,78 @@ int BarUiPianoCall (PianoHandle_t *ph, PianoRequestType_t type,  	return 1;  } -/*	compare stations by name (ignore case) - *	@param station a - *	@param station b - *	@return -1, 0, 1 +/*	Station sorting functions */ + +static inline int BarStationQuickmix01Cmp (const void *a, const void *b) { +	const PianoStation_t *stationA = *((PianoStation_t **) a), +			*stationB = *((PianoStation_t **) b); +	return stationA->isQuickMix - stationB->isQuickMix; +} + +/*	sort by station name from a to z, case insensitive   */ -static int BarStationCmp (const void *a, const void *b) { +static inline int BarStationNameAZCmp (const void *a, const void *b) {  	const PianoStation_t *stationA = *((PianoStation_t **) a),  			*stationB = *((PianoStation_t **) b);  	return strcasecmp (stationA->name, stationB->name);  } +/*	sort by station name from z to a, case insensitive + */ +static int BarStationNameZACmp (const void *a, const void *b) { +	return BarStationNameAZCmp (b, a); +} + +/*	helper for quickmix/name sorting + */ +static inline int BarStationQuickmixNameCmp (const void *a, const void *b, +		const void *c, const void *d) { +	int qmc = BarStationQuickmix01Cmp (a, b); +	return qmc == 0 ? BarStationNameAZCmp (c, d) : qmc; +} + +/*	sort by quickmix (no to yes) and name (a to z) + */ +static int BarStationCmpQuickmix01NameAZ (const void *a, const void *b) { +	return BarStationQuickmixNameCmp (a, b, a, b); +} + +/*	sort by quickmix (no to yes) and name (z to a) + */ +static int BarStationCmpQuickmix01NameZA (const void *a, const void *b) { +	return BarStationQuickmixNameCmp (a, b, b, a); +} + +/*	sort by quickmix (yes to no) and name (a to z) + */ +static int BarStationCmpQuickmix10NameAZ (const void *a, const void *b) { +	return BarStationQuickmixNameCmp (b, a, a, b); +} + +/*	sort by quickmix (yes to no) and name (z to a) + */ +static int BarStationCmpQuickmix10NameZA (const void *a, const void *b) { +	return BarStationQuickmixNameCmp (b, a, b, a); +} +  /*	sort linked list (station)   *	@param stations   *	@return NULL-terminated array with sorted stations   */  PianoStation_t **BarSortedStations (PianoStation_t *unsortedStations, -		size_t *retStationCount) { +		size_t *retStationCount, BarStationSorting_t order) { +	static const BarSortFunc_t orderMapping[] = {BarStationNameAZCmp, +			BarStationNameZACmp, +			BarStationCmpQuickmix01NameAZ, +			BarStationCmpQuickmix01NameZA, +			BarStationCmpQuickmix10NameAZ, +			BarStationCmpQuickmix10NameZA, +			};  	PianoStation_t **stationArray = NULL, *currStation = NULL;  	size_t stationCount = 0, i; +	assert (order < sizeof (orderMapping)/sizeof(*orderMapping)); +  	/* get size */  	currStation = unsortedStations;  	while (currStation != NULL) { @@ -206,7 +261,7 @@ PianoStation_t **BarSortedStations (PianoStation_t *unsortedStations,  		++i;  	} -	qsort (stationArray, stationCount, sizeof (*stationArray), BarStationCmp); +	qsort (stationArray, stationCount, sizeof (*stationArray), orderMapping[order]);  	*retStationCount = stationCount;  	return stationArray; @@ -217,13 +272,13 @@ PianoStation_t **BarSortedStations (PianoStation_t *unsortedStations,   *	@return pointer to selected station or NULL   */  PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt, -		FILE *curFd) { +		BarStationSorting_t order, FILE *curFd) {  	PianoStation_t **sortedStations = NULL, *retStation = NULL;  	size_t stationCount, i;  	int input;  	/* sort and print stations */ -	sortedStations = BarSortedStations (ph->stations, &stationCount); +	sortedStations = BarSortedStations (ph->stations, &stationCount, order);  	for (i = 0; i < stationCount; i++) {  		const PianoStation_t *currStation = sortedStations[i];  		BarUiMsg (MSG_LIST, "%2i) %c%c%c %s\n", i, @@ -35,8 +35,8 @@ typedef enum {MSG_NONE, MSG_INFO, MSG_PLAYING, MSG_TIME, MSG_ERR,  void BarUiMsg (uiMsg_t type, const char *format, ...);  PianoReturn_t BarUiPrintPianoStatus (PianoReturn_t ret); -PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt, -		FILE *curFd); +PianoStation_t *BarUiSelectStation (PianoHandle_t *, const char *, +		BarStationSorting_t, FILE *);  PianoSong_t *BarUiSelectSong (PianoSong_t *startSong, FILE *curFd);  PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd);  char *BarUiSelectMusicId (PianoHandle_t *ph, WaitressHandle_t *, FILE *curFd, char *); diff --git a/src/ui_act.c b/src/ui_act.c index ba7dd1c..7328e40 100644 --- a/src/ui_act.c +++ b/src/ui_act.c @@ -327,7 +327,8 @@ void BarUiActMoveSong (BAR_KS_ARGS) {  	RETURN_IF_NO_SONG; -	reqData.to = BarUiSelectStation (ph, "Move song to station: ", curFd); +	reqData.to = BarUiSelectStation (ph, "Move song to station: ", +			settings->sortOrder, curFd);  	if (reqData.to != NULL) {  		/* find original station (just is case we're playing a quickmix  		 * station) */ @@ -392,7 +393,7 @@ void BarUiActRenameStation (BAR_KS_ARGS) {   */  void BarUiActSelectStation (BAR_KS_ARGS) {  	PianoStation_t *newStation = BarUiSelectStation (ph, "Select station: ", -			curFd); +			settings->sortOrder, curFd);  	if (newStation != NULL) {  		*curStation = newStation;  		BarUiPrintStation ((*curStation)); @@ -450,7 +451,8 @@ void BarUiActSelectQuickMix (BAR_KS_ARGS) {  	if ((*curStation)->isQuickMix) {  		PianoStation_t *selStation;  		while ((selStation = BarUiSelectStation (ph, -				"Toggle quickmix for station: ", curFd)) != NULL) { +				"Toggle quickmix for station: ", settings->sortOrder, +				curFd)) != NULL) {  			selStation->useQuickMix = !selStation->useQuickMix;  		}  		BarUiMsg (MSG_INFO, "Setting quickmix stations... "); | 
