tdiary-contrib 3.2.2.20130518 → 3.2.2.20130614
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -3
- data/doc/ja/plugin/image_gps.txt +56 -17
- data/doc/ja/plugin/playstore.txt +31 -0
- data/js/socialbutton.js +8 -2
- data/lib/exifparser/README +6 -12
- data/lib/tdiary-contrib.rb +7 -6
- data/plugin/brow_si.rb +32 -0
- data/plugin/image_gps.rb +110 -56
- data/plugin/instagr.rb +1 -0
- data/plugin/playstore.rb +161 -0
- data/plugin/tweet_quote.rb +102 -48
- data/plugin/twitter_badge.rb +1 -1
- data/util/estraier-search/estraier-register.rb +2 -1
- data/util/estraier-search/estraier-search.rb +2 -1
- data/util/image-gallery/misc/plugin/recent_image.rb +1 -1
- metadata +7 -27
- data/doc/ja/plugin/image_detail.txt +0 -69
- data/doc/ja/plugin/image_gps2.txt +0 -41
- data/lib/exifparser/BUGS +0 -1
- data/lib/exifparser/ChangeLog +0 -169
- data/lib/exifparser/install.rb +0 -1015
- data/lib/exifparser/lib/exifparser/makernote/canon.rb +0 -502
- data/lib/exifparser/lib/exifparser/makernote/fujifilm.rb +0 -415
- data/lib/exifparser/lib/exifparser/makernote/minolta.rb +0 -84
- data/lib/exifparser/lib/exifparser/makernote/mk_nikonflensname.rb +0 -39
- data/lib/exifparser/lib/exifparser/makernote/nikon.rb +0 -267
- data/lib/exifparser/lib/exifparser/makernote/nikon2.rb +0 -581
- data/lib/exifparser/lib/exifparser/makernote/nikonflensname.rb +0 -438
- data/lib/exifparser/lib/exifparser/makernote/olympus.rb +0 -225
- data/lib/exifparser/lib/exifparser/makernote/prove.rb +0 -84
- data/lib/exifparser/lib/exifparser/makernote/sigma.rb +0 -237
- data/lib/exifparser/lib/exifparser/pre-setup.rb +0 -1
- data/lib/exifparser/lib/exifparser/scan.rb +0 -278
- data/lib/exifparser/lib/exifparser/tag.rb +0 -2298
- data/lib/exifparser/lib/exifparser/thumbnail.rb +0 -76
- data/lib/exifparser/lib/exifparser/utils.rb +0 -88
- data/lib/exifparser/lib/exifparser.rb +0 -265
- data/lib/exifparser/sample/exifview.rb +0 -279
- data/plugin/image_detail.rb +0 -143
@@ -1,76 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# exifparser/thumbnail.rb -
|
3
|
-
#
|
4
|
-
# Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
5
|
-
#
|
6
|
-
# $Revision: 1.1.1.1 $
|
7
|
-
# $Date: 2002/12/16 07:59:00 $
|
8
|
-
#
|
9
|
-
|
10
|
-
module Exif
|
11
|
-
|
12
|
-
class Parser
|
13
|
-
|
14
|
-
alias orig_thumbnail thumbnail
|
15
|
-
|
16
|
-
#
|
17
|
-
# redefine method.
|
18
|
-
#
|
19
|
-
def thumbnail
|
20
|
-
Thumbnail.new(@result[:IFD1], @data)
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
#
|
26
|
-
# APIs are subject to change.
|
27
|
-
#
|
28
|
-
class Thumbnail
|
29
|
-
|
30
|
-
def initialize(ifd1, data)
|
31
|
-
@ifd1 = ifd1
|
32
|
-
@data = data
|
33
|
-
end
|
34
|
-
|
35
|
-
def size
|
36
|
-
@data.size
|
37
|
-
end
|
38
|
-
|
39
|
-
def write(dest)
|
40
|
-
dest << @data
|
41
|
-
end
|
42
|
-
|
43
|
-
def width
|
44
|
-
search_tag('ImageWidth')
|
45
|
-
end
|
46
|
-
|
47
|
-
def height
|
48
|
-
search_tag('ImageLength')
|
49
|
-
end
|
50
|
-
alias length height
|
51
|
-
|
52
|
-
def bits_per_sample
|
53
|
-
search_tag('BitsPerSample')
|
54
|
-
end
|
55
|
-
|
56
|
-
def compression
|
57
|
-
search_tag('Compression')
|
58
|
-
end
|
59
|
-
|
60
|
-
def photometric_interpretation
|
61
|
-
search_tag('PhotometricInterpretation')
|
62
|
-
end
|
63
|
-
|
64
|
-
def strip_offsets
|
65
|
-
search_tag('StripOffsets')
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def search_tag(tag)
|
71
|
-
@ifd1.find { |t| t.name == tag }
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# exifparser/utils.rb -
|
3
|
-
#
|
4
|
-
# Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
5
|
-
#
|
6
|
-
# $Revision: 1.1.1.1 $
|
7
|
-
# $Date: 2002/12/16 07:59:00 $
|
8
|
-
#
|
9
|
-
|
10
|
-
module Exif
|
11
|
-
|
12
|
-
#
|
13
|
-
# utility module that will be included in some classes.
|
14
|
-
#
|
15
|
-
module Utils
|
16
|
-
|
17
|
-
module Decode
|
18
|
-
|
19
|
-
module Motorola
|
20
|
-
|
21
|
-
def byte_order
|
22
|
-
:motorola
|
23
|
-
end
|
24
|
-
|
25
|
-
def decode_ubytes(str)
|
26
|
-
str.unpack('C*')
|
27
|
-
end
|
28
|
-
|
29
|
-
def decode_ushort(str)
|
30
|
-
str[0,2].unpack('n').first
|
31
|
-
end
|
32
|
-
|
33
|
-
def decode_ulong(str)
|
34
|
-
str[0,4].unpack('N').first
|
35
|
-
end
|
36
|
-
|
37
|
-
def decode_sshort(str)
|
38
|
-
str[0,2].unpack('n').pack('s').unpack('s').first
|
39
|
-
end
|
40
|
-
|
41
|
-
def decode_slong(str)
|
42
|
-
str[0,4].unpack('N').pack('l').unpack('l').first
|
43
|
-
end
|
44
|
-
|
45
|
-
def parseTagID(str)
|
46
|
-
sprintf("0x%02x%02x", *(str.unpack("C*")))
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
module Intel
|
53
|
-
|
54
|
-
def byte_order
|
55
|
-
:intel
|
56
|
-
end
|
57
|
-
|
58
|
-
def decode_ubytes(str)
|
59
|
-
str.unpack('C*')
|
60
|
-
end
|
61
|
-
|
62
|
-
def decode_ushort(str)
|
63
|
-
str[0,2].unpack('v').first
|
64
|
-
end
|
65
|
-
|
66
|
-
def decode_ulong(str)
|
67
|
-
str[0,4].unpack('V').first
|
68
|
-
end
|
69
|
-
|
70
|
-
def decode_sshort(str)
|
71
|
-
str[0,2].unpack('s').first
|
72
|
-
end
|
73
|
-
|
74
|
-
def decode_slong(str)
|
75
|
-
str[0,4].unpack('l').first
|
76
|
-
end
|
77
|
-
|
78
|
-
def parseTagID(str)
|
79
|
-
"0x" + str.unpack("C*").reverse.collect{ |e| sprintf("%02x", e) }.join("")
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
end
|
@@ -1,265 +0,0 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
#= exifparser.rb - Exif tag parser written in pure ruby
|
4
|
-
#
|
5
|
-
#Author:: Ryuchi Tamura (r-tam@fsinet.or.jp)
|
6
|
-
#Copyright:: Copyright (C) 2002 Ryuichi Tamura.
|
7
|
-
#
|
8
|
-
# $Id: exifparser.rb,v 1.1.1.1 2002/12/16 07:59:00 tam Exp $
|
9
|
-
#
|
10
|
-
#== INTRODUCTION
|
11
|
-
#
|
12
|
-
#There are 2 classes you work with. ExifParser class is
|
13
|
-
#the Exif tag parser that parses all tags defined EXIF-2.2 standard,
|
14
|
-
#and many of extension tags uniquely defined by some digital equipment
|
15
|
-
#manufacturers. Currently, part of tags defined by FujiFilm, and
|
16
|
-
#Olympus is supported. After initialized with the path to image file
|
17
|
-
#of EXIF format, ExifParser will provides which tags are available in
|
18
|
-
#the image, and how you work with them.
|
19
|
-
#
|
20
|
-
#Tags availble from ExifParser is objects defined under Exif::Tag module,
|
21
|
-
#with its name being the class name. For example if you get "Make" tag
|
22
|
-
#from ExifParser, it is Exif::Tag::DateTime object. Inspecting it looks
|
23
|
-
#following:
|
24
|
-
#
|
25
|
-
# #<Exif::Tag::TIFF::Make ID=0x010f, IFD="IFD0" Name="Make", Format="Ascii" Value="FUJIFILM">
|
26
|
-
#
|
27
|
-
#here, ID is Tag ID defined in EXIF-2.2 standard, IFD is the name of
|
28
|
-
#Image File Directory, Name is String representation of tag ID, Format is
|
29
|
-
#string that shows how the data is formatted, and Value is the value of
|
30
|
-
#the tag. This is retrieved by Exif::Tag::Make#value.
|
31
|
-
#
|
32
|
-
#Another example. If you want to know whether flash was fired when the image
|
33
|
-
#was generated, ExifParser returns Exif::Tag::Flash object:
|
34
|
-
#
|
35
|
-
# tag = exif['Flash']
|
36
|
-
# p tag
|
37
|
-
# => #<Exif::Tag::Exif::Flash ID=0x9209, IFD="Exif" Name="Flash", Format="Unsigned short" Value="1">
|
38
|
-
# p tag.value
|
39
|
-
# => 1
|
40
|
-
#
|
41
|
-
#It may happen that diffrent IFDs have the same tag name. In this case,
|
42
|
-
#use Exif#tag(tagname, IFD)
|
43
|
-
#
|
44
|
-
#The value of the tag above, 1, is not clearly understood
|
45
|
-
#(supposed to be 'true', though). Exif::Tag::Flash#to_s will provides
|
46
|
-
#more human-readable form as String.
|
47
|
-
#
|
48
|
-
# tag.to_s #=> "Flash fired."
|
49
|
-
#
|
50
|
-
#many of these sentences are cited from Exif-2.2 standard.
|
51
|
-
#
|
52
|
-
#== USAGE
|
53
|
-
# require 'exifparser'
|
54
|
-
#
|
55
|
-
# exif = ExifParser.new("fujifilm.jpg")
|
56
|
-
#
|
57
|
-
# 1. get a tag value by its name('Make') or its ID (0x010f)
|
58
|
-
# exif['Make'] #=> 'FUJIFILM'
|
59
|
-
# exif[0x010f] #=> 'FUJIFILM'
|
60
|
-
#
|
61
|
-
# if the specified tag is not found, nil is returned.
|
62
|
-
#
|
63
|
-
# 2. to see the image has the value of specified tag
|
64
|
-
# exif.tag?('DateTime') #=> true
|
65
|
-
# exif.tag?('CameraID') #=> false
|
66
|
-
#
|
67
|
-
# 3. get all the tags contained in the image.
|
68
|
-
#
|
69
|
-
# exif.tags
|
70
|
-
#
|
71
|
-
# or, if you want to know all the tags defined in specific IFD,
|
72
|
-
#
|
73
|
-
# exif.tags(:IFD0) # get all the tags defined in IFD0
|
74
|
-
#
|
75
|
-
# you can traverse each tag and work on it.
|
76
|
-
#
|
77
|
-
# exif.each do |tag|
|
78
|
-
# p tag.to_s
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# # each tag in IFD0
|
82
|
-
# exif.each(:IFD0) do |ifd0_tag|
|
83
|
-
# p ifd0_tag.to_s
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
# 4. extract thumbnail
|
87
|
-
#
|
88
|
-
# File.open("thumb.jpg") do |dest|
|
89
|
-
# exif.thumbnail dest
|
90
|
-
# end
|
91
|
-
#
|
92
|
-
# dest object must respond to '<<'.
|
93
|
-
#
|
94
|
-
require 'exifparser/scan'
|
95
|
-
|
96
|
-
module Exif
|
97
|
-
|
98
|
-
class Parser
|
99
|
-
#
|
100
|
-
# create a new object. fpath is String.
|
101
|
-
#
|
102
|
-
def initialize(fpath)
|
103
|
-
@fpath = fpath
|
104
|
-
@scanner = nil
|
105
|
-
File.open(fpath, "rb") do |f|
|
106
|
-
@scanner = Exif::Scanner.new(f)
|
107
|
-
@scanner.scan
|
108
|
-
end
|
109
|
-
@IFD0 = @scanner.result[:IFD0]
|
110
|
-
@IFD1 = @scanner.result[:IFD1]
|
111
|
-
@Exif = @scanner.result[:Exif]
|
112
|
-
@GPS = @scanner.result[:GPS]
|
113
|
-
@Interoperability = @scanner.result[:Interoperability]
|
114
|
-
@MakerNote = @scanner.result[:MakerNote]
|
115
|
-
@thumbnail = @scanner.result[:Thumbnail]
|
116
|
-
end
|
117
|
-
|
118
|
-
def inspect
|
119
|
-
sprintf("#<%s filename=\"%s\" entries: IFD0(%d) IFD1(%d) Exif(%d) GPS(%d) Interoperability(%d) MakerNote(%d)>", self.class, @fpath, @IFD0.length, @IFD1.length, @Exif.length, @GPS.length, @Interoperability.length, @MakerNote.length)
|
120
|
-
end
|
121
|
-
|
122
|
-
#
|
123
|
-
# return true if specified tagid is defined or has some value.
|
124
|
-
#
|
125
|
-
def tag?(tagid)
|
126
|
-
search_tag(tagid) ? true : false
|
127
|
-
end
|
128
|
-
|
129
|
-
#
|
130
|
-
# search tag on the specific IFD
|
131
|
-
#
|
132
|
-
def tag(tagname, ifd=nil)
|
133
|
-
search_tag(tagname, ifd)
|
134
|
-
end
|
135
|
-
|
136
|
-
#
|
137
|
-
# search the specified tag values. return value is object of
|
138
|
-
# classes defined under Exif::Tag module.
|
139
|
-
#
|
140
|
-
def [](tagname)
|
141
|
-
self.tag(tagname)
|
142
|
-
end
|
143
|
-
|
144
|
-
#
|
145
|
-
# set the specified tag to the specified value.
|
146
|
-
# XXX NOT IMPLEMETED XXX
|
147
|
-
#
|
148
|
-
def []=(tag, value)
|
149
|
-
# not implemented
|
150
|
-
end
|
151
|
-
|
152
|
-
#
|
153
|
-
# extract the thumbnail image to dest. dest should respond to
|
154
|
-
# '<<' method.
|
155
|
-
#
|
156
|
-
def thumbnail(dest)
|
157
|
-
dest << @thumbnail
|
158
|
-
end
|
159
|
-
|
160
|
-
#
|
161
|
-
# return the size of the thumbnail image
|
162
|
-
#
|
163
|
-
def thumbnail_size
|
164
|
-
@thumbnail.size
|
165
|
-
end
|
166
|
-
|
167
|
-
#
|
168
|
-
# return all the tags in the image.
|
169
|
-
#
|
170
|
-
# if argument ifd is specified, every tags defined in the
|
171
|
-
# specified IFD are passed to block.
|
172
|
-
#
|
173
|
-
# return value is object of classes defined under Exif::Tag module.
|
174
|
-
#
|
175
|
-
# allowable arguments are:
|
176
|
-
# * :IFD0
|
177
|
-
# * :IFD1
|
178
|
-
# * :Exif
|
179
|
-
# * :GPS
|
180
|
-
# * :Interoperability
|
181
|
-
# * :MakerNote (if exist)
|
182
|
-
def tags(ifd=nil)
|
183
|
-
if ifd
|
184
|
-
@scanner.result[ifd]
|
185
|
-
else
|
186
|
-
[
|
187
|
-
@IFD0,
|
188
|
-
@IFD1,
|
189
|
-
@Exif,
|
190
|
-
@GPS,
|
191
|
-
@Interoperability,
|
192
|
-
@MakerNote
|
193
|
-
].flatten
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
#
|
198
|
-
# execute given block with block argument being every tags defined
|
199
|
-
# in all the IFDs contained in the image.
|
200
|
-
#
|
201
|
-
# if argument ifd is specified, every tags defined in the
|
202
|
-
# specified IFD are passed to block.
|
203
|
-
#
|
204
|
-
# return value is object of classes defined under Exif::Tag module.
|
205
|
-
#
|
206
|
-
# allowable arguments are:
|
207
|
-
# * :IFD0
|
208
|
-
# * :IFD1
|
209
|
-
# * :Exif
|
210
|
-
# * :GPS
|
211
|
-
# * :Interoperability
|
212
|
-
# * :MakerNote
|
213
|
-
def each(ifd=nil)
|
214
|
-
if ifd
|
215
|
-
@scanner.result[ifd].each{ |tag| yield tag }
|
216
|
-
else
|
217
|
-
[
|
218
|
-
@IFD0,
|
219
|
-
@IFD1,
|
220
|
-
@Exif,
|
221
|
-
@GPS,
|
222
|
-
@Interoperability,
|
223
|
-
@MakerNote
|
224
|
-
].flatten.each do |tag|
|
225
|
-
yield tag
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
private
|
231
|
-
|
232
|
-
def search_tag(tagID, ifd=nil)
|
233
|
-
if ifd
|
234
|
-
@scanner.result(ifd).find do |tag|
|
235
|
-
case tagID
|
236
|
-
when Fixnum
|
237
|
-
tag.tagID.hex == tagID
|
238
|
-
when String
|
239
|
-
tag.name == tagID
|
240
|
-
end
|
241
|
-
end
|
242
|
-
else
|
243
|
-
[
|
244
|
-
@IFD0,
|
245
|
-
@IFD1,
|
246
|
-
@Exif,
|
247
|
-
@GPS,
|
248
|
-
@Interoperability,
|
249
|
-
@MakerNote
|
250
|
-
].flatten.find do |tag|
|
251
|
-
case tagID
|
252
|
-
when Fixnum
|
253
|
-
tag.tagID.hex == tagID
|
254
|
-
when String
|
255
|
-
tag.name == tagID
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
end # module Parser
|
262
|
-
|
263
|
-
end # module Exif
|
264
|
-
|
265
|
-
ExifParser = Exif::Parser
|
@@ -1,279 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# exifview.rb - display EXIF information as well as EXIF image
|
4
|
-
#
|
5
|
-
# Copyright (C) 2002 Ryuichi Tamura (r-tam@fsinet.or.jp)
|
6
|
-
#
|
7
|
-
# $Revision: 1.3 $
|
8
|
-
# $Date: 2002/12/17 05:16:34 $
|
9
|
-
#
|
10
|
-
# Requirements: gtk2
|
11
|
-
#
|
12
|
-
require 'exifparser'
|
13
|
-
require 'observer'
|
14
|
-
require 'gtk2'
|
15
|
-
|
16
|
-
module Exif
|
17
|
-
|
18
|
-
class Parser
|
19
|
-
|
20
|
-
def each_values
|
21
|
-
tags.each do |tag|
|
22
|
-
next if tag == Tag::Exif::MakerNote
|
23
|
-
yield tag.name, tag.tagID.to_s, tag.format, tag.IFD, tag.to_s
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
module ExifView
|
32
|
-
|
33
|
-
class SelectedFile
|
34
|
-
include Observable
|
35
|
-
|
36
|
-
def initialize
|
37
|
-
@fpath = nil
|
38
|
-
end
|
39
|
-
attr_reader :fpath
|
40
|
-
|
41
|
-
def filename=(filename)
|
42
|
-
@fpath = File.expand_path(filename)
|
43
|
-
begin
|
44
|
-
exif = ExifParser.new(@fpath)
|
45
|
-
changed
|
46
|
-
rescue
|
47
|
-
changed(false)
|
48
|
-
raise
|
49
|
-
end
|
50
|
-
notify_observers(@fpath, exif)
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
DisplayImage = SelectedFile.new
|
56
|
-
|
57
|
-
#
|
58
|
-
# Error dialog
|
59
|
-
#
|
60
|
-
class ErrorDialog < ::Gtk::Dialog
|
61
|
-
|
62
|
-
def initialize(msg)
|
63
|
-
super()
|
64
|
-
self.set_default_size(200, 100)
|
65
|
-
self.set_title("ExifView: Error")
|
66
|
-
button = Gtk::Button.new("dismiss")
|
67
|
-
button.flags |= Gtk::Widget::CAN_DEFAULT
|
68
|
-
button.signal_connect("clicked") do destroy end
|
69
|
-
self.action_area.pack_start(button, 0)
|
70
|
-
button.grab_default
|
71
|
-
label = Gtk::Label.new(msg)
|
72
|
-
vbox.pack_start(label)
|
73
|
-
button.show
|
74
|
-
label.show
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
#
|
80
|
-
# File selection
|
81
|
-
#
|
82
|
-
class FileSelectionWidget < ::Gtk::FileSelection
|
83
|
-
|
84
|
-
def initialize
|
85
|
-
super('File selection')
|
86
|
-
history_pulldown
|
87
|
-
self.signal_connect('destroy') { destroy }
|
88
|
-
self.ok_button.signal_connect('clicked') {
|
89
|
-
catch(:read_error) {
|
90
|
-
begin
|
91
|
-
DisplayImage.filename = self.filename
|
92
|
-
rescue
|
93
|
-
ErrorDialog.new($!.message).show
|
94
|
-
throw :read_error
|
95
|
-
end
|
96
|
-
destroy
|
97
|
-
}
|
98
|
-
}
|
99
|
-
self.cancel_button.signal_connect('clicked') { destroy }
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# MenuItem: Open
|
106
|
-
#
|
107
|
-
class OpenMenuItemWidget < ::Gtk::MenuItem
|
108
|
-
|
109
|
-
def initialize
|
110
|
-
super('Open')
|
111
|
-
@filesel = nil
|
112
|
-
self.signal_connect('activate') {
|
113
|
-
@filesel = FileSelectionWidget.new
|
114
|
-
@filesel.show
|
115
|
-
}
|
116
|
-
end
|
117
|
-
attr_reader :filesel
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
#
|
122
|
-
# MenuItem: Quit
|
123
|
-
#
|
124
|
-
class QuitMenuItemWidget < ::Gtk::MenuItem
|
125
|
-
|
126
|
-
def initialize
|
127
|
-
super('Quit')
|
128
|
-
self.signal_connect('activate') { Gtk.main_quit }
|
129
|
-
end
|
130
|
-
|
131
|
-
end
|
132
|
-
|
133
|
-
#
|
134
|
-
# Menu Bar
|
135
|
-
#
|
136
|
-
class MenuBarWidget < ::Gtk::MenuBar
|
137
|
-
|
138
|
-
def initialize
|
139
|
-
super()
|
140
|
-
@item_open = OpenMenuItemWidget.new
|
141
|
-
@item_quit = QuitMenuItemWidget.new
|
142
|
-
menu = Gtk::Menu.new
|
143
|
-
menu.append(@item_open)
|
144
|
-
menu.append(@item_quit)
|
145
|
-
filemenu = Gtk::MenuItem.new("File")
|
146
|
-
filemenu.set_submenu(menu)
|
147
|
-
self.append(filemenu)
|
148
|
-
end
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
class ImageWindow < ::Gtk::ScrolledWindow
|
153
|
-
|
154
|
-
def initialize
|
155
|
-
super(nil, nil)
|
156
|
-
DisplayImage.add_observer(self)
|
157
|
-
@filename = nil
|
158
|
-
@image = Gtk::Image.new
|
159
|
-
@vbox = Gtk::VBox.new(false, 0)
|
160
|
-
self.add_with_viewport(@vbox)
|
161
|
-
self.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
162
|
-
@vbox.pack_start(@image, false, false, 0)
|
163
|
-
end
|
164
|
-
attr_reader :filename
|
165
|
-
|
166
|
-
def update(*args)
|
167
|
-
@filename, = *args
|
168
|
-
@image.set(filename)
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
class ExifDataWindow < ::Gtk::ScrolledWindow
|
174
|
-
|
175
|
-
def initialize
|
176
|
-
super(nil, nil)
|
177
|
-
DisplayImage.add_observer(self)
|
178
|
-
@model, @treeview = setup_columns()
|
179
|
-
end
|
180
|
-
|
181
|
-
def setup_columns
|
182
|
-
model = Gtk::ListStore.new(String, String, String, String, String)
|
183
|
-
# tagname, tag_id, ifd_name, value, respectedly
|
184
|
-
treeview = Gtk::TreeView.new(model)
|
185
|
-
cols = []; i = 0
|
186
|
-
[["Name", 0], ["Number", 1], ["Format", 2],
|
187
|
-
["IFD", 3], ["Value", 4]].each do |e|
|
188
|
-
treeview.insert_column(
|
189
|
-
Gtk::TreeViewColumn.new(e[0], Gtk::CellRendererText.new,
|
190
|
-
{:text => e[1]}), e[1] )
|
191
|
-
end
|
192
|
-
treeview.selection.set_mode(Gtk::SELECTION_SINGLE)
|
193
|
-
self.add_with_viewport(treeview)
|
194
|
-
[model, treeview]
|
195
|
-
end
|
196
|
-
|
197
|
-
def update(*args)
|
198
|
-
fpath, exif = *args
|
199
|
-
@model.clear
|
200
|
-
exif.each_values do |e|
|
201
|
-
set_row(*e)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
private
|
206
|
-
|
207
|
-
def set_row(tagname, tag_id, tag_format, ifd_name, value)
|
208
|
-
iter = @model.append
|
209
|
-
iter.set_value(0, tagname)
|
210
|
-
iter.set_value(1, tag_id)
|
211
|
-
iter.set_value(2, tag_format)
|
212
|
-
iter.set_value(3, ifd_name)
|
213
|
-
iter.set_value(4, value)
|
214
|
-
end
|
215
|
-
|
216
|
-
end
|
217
|
-
|
218
|
-
class MainWindow < ::Gtk::Window
|
219
|
-
|
220
|
-
def initialize(*args)
|
221
|
-
super(*args)
|
222
|
-
DisplayImage.add_observer(self)
|
223
|
-
# Components lower: Exif data
|
224
|
-
@exifdata = ExifDataWindow.new
|
225
|
-
|
226
|
-
# Components middle: Image
|
227
|
-
@image = ImageWindow.new
|
228
|
-
|
229
|
-
# Components upper: Menu bar
|
230
|
-
@menubar = MenuBarWidget.new
|
231
|
-
|
232
|
-
# VBox creation
|
233
|
-
@vbox = Gtk::VBox.new(false, 0)
|
234
|
-
|
235
|
-
# signal connection for toplevel window
|
236
|
-
self.signal_connect('destroy') { exit }
|
237
|
-
self.signal_connect('delete_event') { exit }
|
238
|
-
end
|
239
|
-
|
240
|
-
def initialize_display
|
241
|
-
set_appearance()
|
242
|
-
self.show_all
|
243
|
-
end
|
244
|
-
|
245
|
-
def update(*args)
|
246
|
-
filename, = *args
|
247
|
-
self.set_title("ExifView: #{filename}")
|
248
|
-
end
|
249
|
-
|
250
|
-
private
|
251
|
-
|
252
|
-
def set_appearance
|
253
|
-
# self
|
254
|
-
self.set_size_request(640,480)
|
255
|
-
self.set_title("ExifView #{@image.filename}")
|
256
|
-
self.add(@vbox)
|
257
|
-
# menubar
|
258
|
-
@vbox.pack_start(@menubar, false, false, 0)
|
259
|
-
# image display
|
260
|
-
@vbox.pack_start(@image, true, true, 0)
|
261
|
-
# exif data display
|
262
|
-
@vbox.pack_start(@exifdata, true, true, 0)
|
263
|
-
end
|
264
|
-
|
265
|
-
end
|
266
|
-
|
267
|
-
end
|
268
|
-
|
269
|
-
if $0 == __FILE__
|
270
|
-
Gtk.init
|
271
|
-
#
|
272
|
-
# Main
|
273
|
-
#
|
274
|
-
filename = ARGV.shift
|
275
|
-
window = ExifView::MainWindow.new(Gtk::Window::TOPLEVEL)
|
276
|
-
ExifView::DisplayImage.filename = filename if filename
|
277
|
-
window.initialize_display
|
278
|
-
Gtk.main
|
279
|
-
end
|