On Thu, 2005-08-18 at 19:53 +0200, Baptiste Mille-Mathias wrote: > I can't build RB with the patch applied, please find the message > http://rafb.net/paste/results/QUALJv86.html Oops, it looks like I forgot to upload the two new files that are required. I've uploaded them to bugzilla, and also attached them to this post - they both go in the "widgets" directory. James "Doc" Livingston -- Your mouse has moved. Please restart Windows for the change to take effect
/*
* arch-tag: Header for RhythmDB query creation internals
*
* Copyright (C) 2003, 2004 Colin Walters <walters gnome org>
* Copyright (C) 2005 James Livingston <walters gnome org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <gtk/gtk.h>
#include "rhythmdb.h"
#ifndef __RB_QUERY_CREATOR_PRIVATE_H
#define __RB_QUERY_CREATOR_PRIVATE_H
typedef struct
{
const char *name;
gboolean strict;
RhythmDBPropType val;
} RBQueryCreatorCriteriaOption;
typedef struct
{
const char *name;
const char *sort_key;
} RBQueryCreatorSortOption;
typedef GtkWidget* (*CriteriaCreateWidget) (gboolean *constrain);
typedef void (*CriteriaSetWidgetData) (GtkWidget *widget, GValue *val);
typedef void (*CriteriaGetWidgetData) (GtkWidget *widget, GValue *val);
typedef struct
{
int num_criteria_options;
const RBQueryCreatorCriteriaOption *criteria_options;
CriteriaCreateWidget criteria_create_widget;
CriteriaSetWidgetData criteria_set_widget_data;
CriteriaGetWidgetData criteria_get_widget_data;
} RBQueryCreatorPropertyType;
typedef struct
{
const char *name;
RhythmDBPropType strict_val;
RhythmDBPropType fuzzy_val;
const RBQueryCreatorPropertyType *property_type;
} RBQueryCreatorPropertyOption;
extern const RBQueryCreatorPropertyOption property_options[];
extern const int num_property_options;
extern const RBQueryCreatorSortOption sort_options[];
extern const int num_sort_options;
extern const int DEFAULT_SORTING_COLUMN;
extern const gint DEFAULT_SORTING_ORDER;
GtkWidget * get_box_widget_at_pos (GtkBox *box, guint pos);
#endif /* __RB_QUERY_CREATOR_H */
/*
* arch-tag: Implementation of RhythmDB query creation properties
*
* Copyright (C) 2003, 2004 Colin Walters <walters gnome org>
* Copyright (C) 2005 James Livingston <walters gnome org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <libgnome/gnome-i18n.h>
#include <gtk/gtk.h>
#include "rhythmdb.h"
#include "rb-query-creator-private.h"
#include "rb-rating.h"
const RBQueryCreatorPropertyType string_property_type;
const RBQueryCreatorPropertyType escaped_string_property_type;
const RBQueryCreatorPropertyType rating_property_type;
const RBQueryCreatorPropertyType integer_property_type;
const RBQueryCreatorPropertyType duration_property_type;
const RBQueryCreatorPropertyType relative_time_property_type;
static GtkWidget * stringCriteriaCreateWidget (gboolean *constrain);
static void stringCriteriaSetWidgetData (GtkWidget *widget, GValue *val);
static void stringCriteriaGetWidgetData (GtkWidget *widget, GValue *val);
static void escapedStringCriteriaSetWidgetData (GtkWidget *widget, GValue *val);
static void escapedStringCriteriaGetWidgetData (GtkWidget *widget, GValue *val);
static GtkWidget * ratingCriteriaCreateWidget (gboolean *constrain);
static void ratingCriteriaSetWidgetData (GtkWidget *widget, GValue *val);
static void ratingCriteriaGetWidgetData (GtkWidget *widget, GValue *val);
static GtkWidget * integerCriteriaCreateWidget (gboolean *constrain);
static void integerCriteriaSetWidgetData (GtkWidget *widget, GValue *val);
static void integerCriteriaGetWidgetData (GtkWidget *widget, GValue *val);
static GtkWidget * durationCriteriaCreateWidget (gboolean *constrain);
static void durationCriteriaSetWidgetData (GtkWidget *widget, GValue *val);
static void durationCriteriaGetWidgetData (GtkWidget *widget, GValue *val);
static GtkWidget * relativeTimeCriteriaCreateWidget (gboolean *constrain);
static void relativeTimeCriteriaSetWidgetData (GtkWidget *widget, GValue *val);
static void relativeTimeCriteriaGetWidgetData (GtkWidget *widget, GValue *val);
/*
* This table is the list of properties that are displayed in the query-creator
*/
const RBQueryCreatorPropertyOption property_options[] =
{
{ N_("Title"), RHYTHMDB_PROP_TITLE, RHYTHMDB_PROP_TITLE_FOLDED, &string_property_type },
{ N_("Artist"), RHYTHMDB_PROP_ARTIST, RHYTHMDB_PROP_ARTIST_FOLDED, &string_property_type },
{ N_("Album"), RHYTHMDB_PROP_ALBUM, RHYTHMDB_PROP_ALBUM_FOLDED, &string_property_type },
{ N_("Genre"), RHYTHMDB_PROP_GENRE, RHYTHMDB_PROP_GENRE_FOLDED, &string_property_type },
{ N_("Rating"), RHYTHMDB_PROP_RATING, RHYTHMDB_PROP_RATING, &rating_property_type },
{ N_("Path"), RHYTHMDB_PROP_LOCATION, RHYTHMDB_PROP_LOCATION, &escaped_string_property_type },
{ N_("Play Count"), RHYTHMDB_PROP_PLAY_COUNT, RHYTHMDB_PROP_PLAY_COUNT, &integer_property_type },
{ N_("Track Number"), RHYTHMDB_PROP_TRACK_NUMBER, RHYTHMDB_PROP_TRACK_NUMBER, &integer_property_type },
{ N_("Disc Number"), RHYTHMDB_PROP_DISC_NUMBER, RHYTHMDB_PROP_DISC_NUMBER, &integer_property_type },
{ N_("Bitrate"), RHYTHMDB_PROP_BITRATE, RHYTHMDB_PROP_BITRATE, &integer_property_type },
{ N_("Duration"), RHYTHMDB_PROP_DURATION, RHYTHMDB_PROP_DURATION, &duration_property_type },
{ N_("Last Played"), RHYTHMDB_PROP_LAST_PLAYED, RHYTHMDB_PROP_LAST_PLAYED, &relative_time_property_type },
{ N_("First Seen"), RHYTHMDB_PROP_FIRST_SEEN, RHYTHMDB_PROP_FIRST_SEEN, &relative_time_property_type },
};
const int num_property_options = G_N_ELEMENTS (property_options);
/*
* This table describes which properties can be used for sorting a playlist
* All entries MUST have column keys column keys listed in rb-entry-view.c
*/
const RBQueryCreatorSortOption sort_options[] =
{
{ N_("Artist"), "Artist" },
{ N_("Album"), "Album" },
{ N_("Genre"), "Genre" },
{ N_("Title"), "Title" },
{ N_("Year"), "Year" },
{ N_("Rating"), "Rating" },
{ N_("Play Count"), "PlayCount" },
{ N_("Track Number"), "Track"},
{ N_("Duration"), "Time" },
{ N_("Last Played"), "LastPlayed" }
};
const int num_sort_options = G_N_ELEMENTS (sort_options);
const int DEFAULT_SORTING_COLUMN = 0;
const gint DEFAULT_SORTING_ORDER = GTK_SORT_ASCENDING;
/*
* This is the property type for string properties
*/
const RBQueryCreatorCriteriaOption string_criteria_options[] =
{
{ N_("contains"), 0, RHYTHMDB_QUERY_PROP_LIKE },
{ N_("does not contain"), 0, RHYTHMDB_QUERY_PROP_NOT_LIKE },
{ N_("equals"), 1, RHYTHMDB_QUERY_PROP_EQUALS }
};
const RBQueryCreatorPropertyType string_property_type =
{
G_N_ELEMENTS (string_criteria_options),
string_criteria_options,
stringCriteriaCreateWidget,
stringCriteriaSetWidgetData,
stringCriteriaGetWidgetData
};
const RBQueryCreatorPropertyType escaped_string_property_type =
{
G_N_ELEMENTS (string_criteria_options),
string_criteria_options,
stringCriteriaCreateWidget,
escapedStringCriteriaSetWidgetData,
escapedStringCriteriaGetWidgetData
};
/*
* This are the property types for numeric quantities, such as rating and playcounts
*/
const RBQueryCreatorCriteriaOption numeric_criteria_options[] =
{
{ N_("equals"), 1, RHYTHMDB_QUERY_PROP_EQUALS },
{ N_("at least"), 1, RHYTHMDB_QUERY_PROP_GREATER }, /* matches if A >= B */
{ N_("at most"), 1, RHYTHMDB_QUERY_PROP_LESS } /* matches if A <= B */
};
const RBQueryCreatorPropertyType rating_property_type =
{
G_N_ELEMENTS (numeric_criteria_options),
numeric_criteria_options,
ratingCriteriaCreateWidget,
ratingCriteriaSetWidgetData,
ratingCriteriaGetWidgetData
};
const RBQueryCreatorPropertyType integer_property_type =
{
G_N_ELEMENTS (numeric_criteria_options),
numeric_criteria_options,
integerCriteriaCreateWidget,
integerCriteriaSetWidgetData,
integerCriteriaGetWidgetData
};
const RBQueryCreatorPropertyType duration_property_type =
{
G_N_ELEMENTS (numeric_criteria_options),
numeric_criteria_options,
durationCriteriaCreateWidget,
durationCriteriaSetWidgetData,
durationCriteriaGetWidgetData
};
/*
* This is the property type for relative time properties, such as last played and first seen
*/
typedef struct
{
const char *name;
gulong timeMultiplier;
} RBQueryCreatorTimeUnitOption;
const RBQueryCreatorCriteriaOption relative_time_criteria_options[] =
{
/*
* Translators: this will match when within <value> of the current time
* e.g. "in the last" "7 days" will match if within 7 days of the current time
*/
{ N_("in the last"), 1, RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN },
/*
* Translators: this is the opposite of the above, and will match if not
* within <value> of the current time
*/
{ N_("not in the last"), 1, RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN }
};
const RBQueryCreatorPropertyType relative_time_property_type =
{
G_N_ELEMENTS (relative_time_criteria_options),
relative_time_criteria_options,
relativeTimeCriteriaCreateWidget,
relativeTimeCriteriaSetWidgetData,
relativeTimeCriteriaGetWidgetData
};
const RBQueryCreatorTimeUnitOption time_unit_options[] =
{
{ N_("seconds"), 1 },
{ N_("minutes"), 60 },
{ N_("hours"), 60 * 60 },
{ N_("days"), 60 * 60 * 24 },
{ N_("weeks"), 60 * 60 * 24 * 7 }
};
const int time_unit_options_default = 4; /* days */
/*
* Implementation for the string properties, using a single GtkEntry.
*/
static GtkWidget *
stringCriteriaCreateWidget (gboolean *constrain)
{
return gtk_entry_new ();
}
static void
stringCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
{
gtk_entry_set_text (GTK_ENTRY (widget), g_value_get_string (val));
}
static void
stringCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
{
const char* text = gtk_entry_get_text (GTK_ENTRY (widget));
g_value_init (val, G_TYPE_STRING);
g_value_set_string (val, text);
}
/* escaped string operations, for use with URIs, etc */
static void
escapedStringCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
{
char *text = gnome_vfs_unescape_string (g_value_get_string (val), NULL);
gtk_entry_set_text (GTK_ENTRY (widget), text);
g_free (text);
}
static void
escapedStringCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
{
char *text = gnome_vfs_escape_path_string (gtk_entry_get_text (GTK_ENTRY (widget)));
g_value_init (val, G_TYPE_STRING);
g_value_set_string (val, text);
}
/*
* Implementation for the ratings property, using the RbRating widget
*/
static void
set_rating_score (RBRating *rating, gdouble score)
{
g_object_set (G_OBJECT (rating), "rating", score, NULL);
}
static GtkWidget *
ratingCriteriaCreateWidget (gboolean *constrain)
{
RBRating *rating = rb_rating_new ();
g_signal_connect_object (G_OBJECT (rating), "rated",
G_CALLBACK (set_rating_score), NULL, 0);
*constrain = FALSE;
return GTK_WIDGET (rating);
}
static void
ratingCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
{
g_object_set (G_OBJECT (widget), "rating", g_value_get_double (val), NULL);
}
static void
ratingCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
{
double rating;
g_object_get (G_OBJECT (widget), "rating", &rating, NULL);
g_value_init (val, G_TYPE_DOUBLE);
g_value_set_double (val, rating);
}
/*
* Implementation for the integer properties, using a single GtkSpinButton.
*/
static GtkWidget *
integerCriteriaCreateWidget (gboolean *constrain)
{
return gtk_spin_button_new_with_range (0.0, (double)G_MAXINT, 1.0);
}
static void
integerCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
{
gulong num = g_value_get_ulong (val);
g_assert (num <= G_MAXINT);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), (gint)num );
}
static void
integerCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
{
gint num = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
g_assert (num >= 0);
g_value_init (val, G_TYPE_ULONG);
g_value_set_ulong (val, (gulong)num);
}
/*
* Implementation for the duration property, using two single GtkSpinButtons.
*/
static GtkWidget *
durationCriteriaCreateWidget (gboolean *constrain)
{
GtkBox *box;
GtkWidget *minutesSpin;
GtkWidget *minutesLabel;
GtkWidget *secondsSpin;
/* the widget for Duration is set out like the following [ 2] : [30] */
box = GTK_BOX (gtk_hbox_new (FALSE, 3));
minutesSpin = gtk_spin_button_new_with_range (0.0, G_MAXINT, 1.0);
gtk_box_pack_start (box, minutesSpin, FALSE, FALSE, 0);
minutesLabel = gtk_label_new (":");
gtk_box_pack_start (box, minutesLabel, FALSE, FALSE, 0);
secondsSpin = gtk_spin_button_new_with_range (0.0, 59.0, 1.0);
gtk_box_pack_start (box, secondsSpin, FALSE, FALSE, 0);
gtk_widget_show_all (GTK_WIDGET (box));
return GTK_WIDGET (box);
}
static void
durationCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
{
GtkSpinButton *minutesSpinner = GTK_SPIN_BUTTON (get_box_widget_at_pos (GTK_BOX (widget), 0));
GtkSpinButton *secondsSpinner = GTK_SPIN_BUTTON (get_box_widget_at_pos (GTK_BOX (widget), 2));
gtk_spin_button_set_value (minutesSpinner, (gdouble) (g_value_get_ulong (val) / 60));
gtk_spin_button_set_value (secondsSpinner, (gdouble) (g_value_get_ulong (val) % 60));
}
static void
durationCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
{
GtkSpinButton *minutesSpinner = GTK_SPIN_BUTTON (get_box_widget_at_pos (GTK_BOX (widget), 0));
GtkSpinButton *secondsSpinner = GTK_SPIN_BUTTON (get_box_widget_at_pos (GTK_BOX (widget), 2));
gint value = gtk_spin_button_get_value_as_int (minutesSpinner) * 60
+ gtk_spin_button_get_value_as_int (secondsSpinner);
g_assert (value >= 0);
g_value_init (val, G_TYPE_ULONG);
g_value_set_ulong (val, (gulong) value);
}
/*
* Implementation for the relative time properties, using a spin button and a menu.
*/
static GtkWidget*
create_time_unit_option_menu (const RBQueryCreatorTimeUnitOption *options,
int length)
{
GtkWidget *menu = gtk_menu_new ();
GtkWidget *option_menu = gtk_option_menu_new ();
int i;
for (i = 0; i < length; i++) {
GtkWidget *menu_item = gtk_menu_item_new_with_label (_(options[i].name));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
}
gtk_widget_show_all (menu);
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
return option_menu;
}
static GtkWidget *
relativeTimeCriteriaCreateWidget (gboolean *constrain)
{
GtkBox *box;
GtkWidget *timeSpin;
GtkWidget *timeOption;
box = GTK_BOX (gtk_hbox_new (FALSE, 6));
timeSpin = gtk_spin_button_new_with_range (1.0, G_MAXINT, 1.0);
gtk_box_pack_start_defaults (box, timeSpin);
timeOption = create_time_unit_option_menu (time_unit_options, G_N_ELEMENTS (time_unit_options));
gtk_option_menu_set_history(GTK_OPTION_MENU (timeOption), time_unit_options_default);
gtk_box_pack_start_defaults (box, timeOption);
gtk_widget_show_all (GTK_WIDGET (box));
return GTK_WIDGET (box);
}
static void
relativeTimeCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
{
GtkBox *box = GTK_BOX (widget);
GtkSpinButton *timeSpin = GTK_SPIN_BUTTON (get_box_widget_at_pos (box, 0));
GtkOptionMenu *unitMenu = GTK_OPTION_MENU (get_box_widget_at_pos (box, 1));
gulong time = g_value_get_ulong (val);
gulong unit = 0;
int i;
/* determine the best units to use for the given value */
for (i = 0; i < G_N_ELEMENTS(time_unit_options); i++) {
/* find out if the time is an even multiple of the unit */
if (time % time_unit_options[i].timeMultiplier == 0)
unit = i;
}
time = time / time_unit_options[unit].timeMultiplier;
g_assert (time < G_MAXINT);
/* set the time value and unit*/
gtk_option_menu_set_history(unitMenu, unit);
gtk_spin_button_set_value(timeSpin, time);
}
static void
relativeTimeCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
{
GtkSpinButton *timeSpin = GTK_SPIN_BUTTON (get_box_widget_at_pos (GTK_BOX (widget), 0));
GtkOptionMenu *unitMenu = GTK_OPTION_MENU (get_box_widget_at_pos (GTK_BOX (widget), 1));
gulong timeMultiplier = time_unit_options [gtk_option_menu_get_history (unitMenu)].timeMultiplier;
gint value = gtk_spin_button_get_value_as_int (timeSpin) * timeMultiplier;
g_assert (value >= 0);
g_value_init (val, G_TYPE_ULONG);
g_value_set_ulong (val, (gulong) value);
}
Attachment:
signature.asc
Description: This is a digitally signed message part