Commit 1f49f160 authored by Jim Nelson's avatar Jim Nelson

#296: Now with configure script to set installation prefix. Also, moved all...

#296: Now with configure script to set installation prefix.  Also, moved all .ui files into separate directory.  Shotwell determines whether to use local or installed resources files at runtime.
parent 66f1ec31
......@@ -25,7 +25,7 @@ public class FullscreenWindow : Gtk.Window {
public FullscreenWindow(Gdk.Screen screen, CheckerboardPage controller, Thumbnail start) {
photo_page = new PhotoPage(this);
File ui_file = AppWindow.get_ui_dir().get_child("fullscreen.ui");
File ui_file = Resources.get_ui("fullscreen.ui");
try {
ui.add_ui_from_file(ui_file.get_path());
......@@ -193,7 +193,7 @@ public class FullscreenWindow : Gtk.Window {
public class AppWindow : Gtk.Window {
public static const string TITLE = "Shotwell";
public static const string VERSION = "0.0.1";
public static const string VERSION = "0.1";
public static const string DATA_DIR = ".photo";
public static const string PHOTOS_DIR = "Pictures";
......@@ -281,15 +281,16 @@ public class AppWindow : Gtk.Window {
return subdir;
}
public static File get_ui_dir() {
// TODO: Programatically determine where runtime data is stored from API calls ...
// for now, this uses the installed data if running from /usr, otherwise looks for
// them in the executable's folder
if (AppWindow.get_exec_dir().get_path().has_prefix("/usr")) {
return File.new_for_path("/usr/local/share/shotwell");
} else {
public static File get_resources_dir() {
File exec_dir = get_exec_dir();
File prefix_dir = File.new_for_path(PREFIX);
// if running in the prefix'd path, the app has been installed and is running from there;
// use its installed resources; otherwise running locally, so use local resources
if (exec_dir.has_prefix(prefix_dir))
return prefix_dir.get_child("share").get_child("shotwell");
else
return AppWindow.get_exec_dir();
}
}
public static void error_message(string message) {
......
......@@ -74,8 +74,8 @@ public class CollectionPage : CheckerboardPage {
{ "PhotosMenu", null, "_Photos", null, null, on_photos_menu },
{ "IncreaseSize", Gtk.STOCK_ZOOM_IN, "Zoom _In", "bracketright", "Increase the magnification of the thumbnails", on_increase_size },
{ "DecreaseSize", Gtk.STOCK_ZOOM_OUT, "Zoom _Out", "bracketleft", "Decrease the magnification of the thumbnails", on_decrease_size },
{ "RotateClockwise", STOCK_CLOCKWISE, "Rotate _Right", "<Ctrl>R", "Rotate the selected photos clockwise", on_rotate_clockwise },
{ "RotateCounterclockwise", STOCK_COUNTERCLOCKWISE, "Rotate _Left", "<Ctrl><Shift>R", "Rotate the selected photos counterclockwise", on_rotate_counterclockwise },
{ "RotateClockwise", Resources.STOCK_CLOCKWISE, "Rotate _Right", "<Ctrl>R", "Rotate the selected photos clockwise", on_rotate_clockwise },
{ "RotateCounterclockwise", Resources.STOCK_COUNTERCLOCKWISE, "Rotate _Left", "<Ctrl><Shift>R", "Rotate the selected photos counterclockwise", on_rotate_counterclockwise },
{ "Mirror", null, "_Mirror", "<Ctrl>M", "Make mirror images of the selected photos", on_mirror },
{ "Revert", Gtk.STOCK_REVERT_TO_SAVED, "Re_vert to Original", null, "Revert to original photo", on_revert },
......@@ -120,7 +120,7 @@ public class CollectionPage : CheckerboardPage {
// set up page's toolbar (used by AppWindow for layout)
//
// rotate tool
rotate_button = new Gtk.ToolButton.from_stock(STOCK_CLOCKWISE);
rotate_button = new Gtk.ToolButton.from_stock(Resources.STOCK_CLOCKWISE);
rotate_button.label = "Rotate";
rotate_button.sensitive = false;
rotate_button.clicked += on_rotate_clockwise;
......@@ -620,7 +620,7 @@ public class CollectionPage : CheckerboardPage {
}
private override bool on_ctrl_pressed(Gdk.EventKey event) {
rotate_button.set_stock_id(STOCK_COUNTERCLOCKWISE);
rotate_button.set_stock_id(Resources.STOCK_COUNTERCLOCKWISE);
rotate_button.clicked -= on_rotate_clockwise;
rotate_button.clicked += on_rotate_counterclockwise;
......@@ -628,7 +628,7 @@ public class CollectionPage : CheckerboardPage {
}
private override bool on_ctrl_released(Gdk.EventKey event) {
rotate_button.set_stock_id(STOCK_CLOCKWISE);
rotate_button.set_stock_id(Resources.STOCK_CLOCKWISE);
rotate_button.clicked -= on_rotate_counterclockwise;
rotate_button.clicked += on_rotate_clockwise;
......
TARGET = shotwell
VALAC = valac
INSTALL_PROGRAM = install
INSTALL_DATA = install -m 644
VALAFLAGS = -g --enable-checking
ifdef dev
DEVFLAGS = --save-temps
endif
# C99 takes care of a warning message generated by the use of Math.round in image_util.vala
VALAC_OPTS =--Xcc=-std=c99 -g --enable-checking
ALL_VALAFLAGS = $(VALAFLAGS) $(DEVFLAGS) --Xcc=-std=c99
PREFIX=/usr/local
DESKTOP_DIR=/usr/share/applications
-include configure.in
SRC_FILES = \
main.vala \
......@@ -26,8 +39,9 @@ SRC_FILES = \
Orientation.vala \
util.vala \
BatchImport.vala \
ExportDialog.vala
ExportDialog.vala \
Resources.vala
VAPI_FILES = \
libexif.vapi \
fstream.vapi \
......@@ -41,7 +55,7 @@ RESOURCE_FILES = \
HEADER_FILES = \
gphoto.h
VAPI_DIRS = \
.
......@@ -67,26 +81,32 @@ all: $(TARGET)
clean:
rm -f *.c
rm -f $(CONFIG_IN)
rm -f $(TARGET)
cleantemps:
rm -f *.c
install: $(TARGET) shotwell.desktop
cp $(TARGET) /usr/local/bin
mkdir -p /usr/local/share/shotwell/icons
cp icons/* /usr/local/share/shotwell/icons
$(foreach res,$(RESOURCE_FILES),cp $(res) /usr/local/share/shotwell;)
cp shotwell.desktop /usr/share/applications
$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(PREFIX)/bin
mkdir -p $(DESTDIR)$(PREFIX)/share/shotwell/icons
$(INSTALL_DATA) icons/* $(DESTDIR)$(PREFIX)/share/shotwell/icons
mkdir -p $(DESTDIR)$(PREFIX)/share/shotwell/ui
$(INSTALL_DATA) ui/* $(DESTDIR)$(PREFIX)/share/shotwell/ui
$(INSTALL_DATA) shotwell.desktop $(DESTDIR)$(DESKTOP_DIR)
uninstall:
rm -f /usr/local/bin/$(TARGET)
rm -fr /usr/local/share/shotwell
rm -f /usr/share/applications/shotwell.desktop
rm -f $(DESTDIR)$(PREFIX)/bin/$(TARGET)
rm -fr $(DESTDIR)$(PREFIX)/share/shotwell
rm -f $(DESTDIR)$(DESKTOP_DIR)/shotwell.desktop
$(TARGET): $(SRC_FILES) $(VAPI_FILES) $(HEADER_FILES) Makefile
$(TARGET): $(SRC_FILES) $(VAPI_FILES) $(HEADER_FILES) Makefile configure $(CONFIG_IN)
pkg-config --print-errors --exists $(EXT_PKGS)
valac $(VALAC_OPTS) \
$(VALAC) $(ALL_VALAFLAGS) \
$(foreach pkg,$(PKGS),--pkg=$(pkg)) \
$(foreach vapidir,$(VAPI_DIRS), --vapidir=$(vapidir)) \
$(foreach hdir,$(HEADER_DIRS),-X -I$(hdir)) \
-X -DPREFIX='"$(PREFIX)"' \
$(SRC_FILES) \
-o $(TARGET)
......@@ -20,9 +20,6 @@ public abstract class Page : Gtk.ScrolledWindow {
public static const uint KEY_ALT_L = Gdk.keyval_from_name("Alt_L");
public static const uint KEY_ALT_R = Gdk.keyval_from_name("Alt_R");
public static const string STOCK_CLOCKWISE = "shotwell-rotate-clockwise";
public static const string STOCK_COUNTERCLOCKWISE = "shotwell-rotate-counterclockwise";
protected enum TargetType {
URI_LIST
}
......@@ -32,33 +29,6 @@ public abstract class Page : Gtk.ScrolledWindow {
{ "text/uri-list", Gtk.TargetFlags.OTHER_APP, TargetType.URI_LIST }
};
private static Gtk.IconFactory factory = null;
private static void add_stock_icon(File file, string stock_id) {
Gdk.Pixbuf pixbuf = null;
try {
pixbuf = new Gdk.Pixbuf.from_file(file.get_path());
} catch (Error err) {
error("%s", err.message);
}
Gtk.IconSet icon_set = new Gtk.IconSet.from_pixbuf(pixbuf);
factory.add(stock_id, icon_set);
}
private static void prep_icons() {
if (factory != null)
return;
factory = new Gtk.IconFactory();
File icons_dir = AppWindow.get_ui_dir().get_child("icons");
add_stock_icon(icons_dir.get_child("object-rotate-right.svg"), STOCK_CLOCKWISE);
add_stock_icon(icons_dir.get_child("object-rotate-left.svg"), STOCK_COUNTERCLOCKWISE);
factory.add_default();
}
public Gtk.UIManager ui = new Gtk.UIManager();
public Gtk.ActionGroup action_group = null;
......@@ -68,10 +38,6 @@ public abstract class Page : Gtk.ScrolledWindow {
private Gtk.Widget event_source = null;
private bool dnd_enabled = false;
public Page() {
prep_icons();
}
public void set_event_source(Gtk.Widget event_source) {
assert(this.event_source == null);
......@@ -134,12 +100,12 @@ public abstract class Page : Gtk.ScrolledWindow {
}
protected void init_load_ui(string ui_filename) {
File ui_file = AppWindow.get_ui_dir().get_child(ui_filename);
File ui_file = Resources.get_ui(ui_filename);
try {
ui.add_ui_from_file(ui_file.get_path());
} catch (Error gle) {
error("Error loading UI file %s: %s", ui_filename, gle.message);
error("Error loading UI file %s: %s", ui_file.get_path(), gle.message);
}
}
......
......@@ -121,10 +121,10 @@ public class PhotoPage : Page {
{ "ReturnToPage", null, "_Return to Collection", "Escape", null, on_return_to_collection },
{ "PhotoMenu", null, "_Photo", null, null, on_photo_menu },
{ "PrevPhoto", Gtk.STOCK_GO_BACK, "_Previous Photo", null, "Previous Photo", on_previous_photo },
{ "NextPhoto", Gtk.STOCK_GO_FORWARD, "_Next Photo", null, "Next Photo", on_next_photo },
{ "RotateClockwise", STOCK_CLOCKWISE, "Rotate _Right", "<Ctrl>R", "Rotate the selected photos clockwise", on_rotate_clockwise },
{ "RotateCounterclockwise", STOCK_COUNTERCLOCKWISE, "Rotate _Left", "<Ctrl><Shift>R", "Rotate the selected photos counterclockwise", on_rotate_counterclockwise },
{ "PrevPhoto", Gtk.STOCK_GO_BACK, "_Previous Photo", "<Alt>Left", "Previous Photo", on_previous_photo },
{ "NextPhoto", Gtk.STOCK_GO_FORWARD, "_Next Photo", "<Alt>Right", "Next Photo", on_next_photo },
{ "RotateClockwise", Resources.STOCK_CLOCKWISE, "Rotate _Right", "<Ctrl>R", "Rotate the selected photos clockwise", on_rotate_clockwise },
{ "RotateCounterclockwise", Resources.STOCK_COUNTERCLOCKWISE, "Rotate _Left", "<Ctrl><Shift>R", "Rotate the selected photos counterclockwise", on_rotate_counterclockwise },
{ "Mirror", null, "_Mirror", "<Ctrl>M", "Make mirror images of the selected photos", on_mirror },
{ "Revert", Gtk.STOCK_REVERT_TO_SAVED, "Re_vert to Original", null, "Revert to the original photo", on_revert },
......@@ -141,7 +141,7 @@ public class PhotoPage : Page {
// set up page's toolbar (used by AppWindow for layout and FullscreenWindow as a popup)
//
// rotate tool
rotate_button = new Gtk.ToolButton.from_stock(STOCK_CLOCKWISE);
rotate_button = new Gtk.ToolButton.from_stock(Resources.STOCK_CLOCKWISE);
rotate_button.set_label("Rotate");
rotate_button.clicked += on_rotate_clockwise;
toolbar.insert(rotate_button, -1);
......@@ -847,7 +847,7 @@ public class PhotoPage : Page {
}
private override bool on_ctrl_pressed(Gdk.EventKey event) {
rotate_button.set_stock_id(STOCK_COUNTERCLOCKWISE);
rotate_button.set_stock_id(Resources.STOCK_COUNTERCLOCKWISE);
rotate_button.clicked -= on_rotate_clockwise;
rotate_button.clicked += on_rotate_counterclockwise;
......@@ -855,7 +855,7 @@ public class PhotoPage : Page {
}
private override bool on_ctrl_released(Gdk.EventKey event) {
rotate_button.set_stock_id(STOCK_CLOCKWISE);
rotate_button.set_stock_id(Resources.STOCK_CLOCKWISE);
rotate_button.clicked -= on_rotate_counterclockwise;
rotate_button.clicked += on_rotate_clockwise;
......
// defined by ./configure and included by gcc -D
extern const string PREFIX;
namespace Resources {
public const string STOCK_CLOCKWISE = "shotwell-rotate-clockwise";
public const string STOCK_COUNTERCLOCKWISE = "shotwell-rotate-counterclockwise";
private Gtk.IconFactory factory = null;
public void init () {
factory = new Gtk.IconFactory();
File icons_dir = AppWindow.get_resources_dir().get_child("icons");
add_stock_icon(icons_dir.get_child("object-rotate-right.svg"), STOCK_CLOCKWISE);
add_stock_icon(icons_dir.get_child("object-rotate-left.svg"), STOCK_COUNTERCLOCKWISE);
factory.add_default();
}
public void terminate() {
}
public File get_ui(string filename) {
return AppWindow.get_resources_dir().get_child("ui").get_child(filename);
}
private void add_stock_icon(File file, string stock_id) {
Gdk.Pixbuf pixbuf = null;
try {
pixbuf = new Gdk.Pixbuf.from_file(file.get_path());
} catch (Error err) {
error("%s", err.message);
}
Gtk.IconSet icon_set = new Gtk.IconSet.from_pixbuf(pixbuf);
factory.add(stock_id, icon_set);
}
}
......@@ -33,14 +33,24 @@ public class ThumbnailCache : Object {
public static void import(PhotoID photo_id, Gdk.Pixbuf original, bool force = false) {
big._import(photo_id, original, force);
spin_event_loop();
medium._import(photo_id, original, force);
spin_event_loop();
small._import(photo_id, original, force);
spin_event_loop();
}
public static void remove(PhotoID photo_id) {
big._remove(photo_id);
spin_event_loop();
medium._remove(photo_id);
spin_event_loop();
small._remove(photo_id);
spin_event_loop();
}
public static Gdk.Pixbuf? fetch(PhotoID photo_id, int scale) {
......
#! /bin/sh
CONFIG_IN=configure.in
configure_help() {
printf "\nUsage:\n"
printf "\t./configure [OPTIONS]...\n"
printf "\n"
printf "Options:\n"
printf "\t-h, --help\t\tPrint this help and exit.\n"
printf "\t--prefix=PREFIX\t\tPrepend PREFIX to program installation paths.\n"
printf "\t\t\t\t[/usr/local]\n\n"
}
abort() {
printf "%s: Invalid argument %s\n" $0 $1
configure_help
exit 1
}
while [ $# != 0 ]
do
option=`echo $1 | sed 's/=.*//'`
if [ `echo $1 | grep '='` ]
then
value=`echo $1 | sed 's/.*=//'`
fi
case $option in
-h | --help) configure_help
exit 0
;;
--prefix) if [ ! $value ]
then
abort $1
fi
variables="${variables}PREFIX=$value\n"
;;
*) abort $1
;;
esac
shift
done
rm -f $CONFIG_IN
touch $0
if [ $variables ]
then
echo -n $variables > $CONFIG_IN
echo "CONFIG_IN=${CONFIG_IN}" >> $CONFIG_IN
fi
printf "Configured. Type 'make' to build, 'make install' to install.\n"
......@@ -61,6 +61,7 @@ void main(string[] args) {
// initialize app-wide stuff
AppWindow.init(args);
Resources.init();
DatabaseTable.init();
ThumbnailCache.init();
Photo.init();
......@@ -74,26 +75,25 @@ void main(string[] args) {
+ "It appears it was created by Shotwell %s. Please use that version or later.", app_version);
dialog.run();
dialog.destroy();
} else {
// create main application window
AppWindow app_window = new AppWindow();
// report mount points
foreach (string mount in mounts)
app_window.mounted_camera_shell_notification(File.new_for_uri(mount));
// throw it all on the display
app_window.show_all();
return;
// event loop
Gtk.main();
}
// create main application window
AppWindow app_window = new AppWindow();
// report mount points
foreach (string mount in mounts)
app_window.mounted_camera_shell_notification(File.new_for_uri(mount));
// throw it all on the display
app_window.show_all();
// event loop
Gtk.main();
Photo.terminate();
ThumbnailCache.terminate();
DatabaseTable.terminate();
Resources.terminate();
AppWindow.terminate();
}
[Desktop Entry]
Version=1.0
Version=0.1
Name=Shotwell
GenericName=Photo Organizer
Comment=Import and organize your photos.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment