mireru 0.2.1 → 0.9.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ebe6191f01182968abdb9fdfb6b3e9f409e7a34
4
- data.tar.gz: d64056047895dbf66885ce81b2fdb10ed1a7e905
3
+ metadata.gz: fdbbb02cb56552275b740544a7156e7b155bd126
4
+ data.tar.gz: efb1f67b291ec5733cf9499f6ca71cb4969251cd
5
5
  SHA512:
6
- metadata.gz: a03ed7b019779753b3eddb07bed3aecc9a4f30cbd96665838909ef1ed3c393d4d81fb91063ccbbcaa5d30c7c571620b5586c076deec62c2cb1fe655b98cc34d2
7
- data.tar.gz: 24dd3afe0d6f16091a384cc08db23eeae127daa84ec7b90a69df998bbb31570b9ef2552d00f65197ba74396174f9042c360ec8fb468ac3f453f56ce089523ac0
6
+ metadata.gz: d73f9d68826bb2dc43fa3a9719e1b1d053bfe119a33c194660c26dfbdb7223ebfd5a3b6a292239a6f30e4841066ec552313be858edc719d72e10dba6e09a970d
7
+ data.tar.gz: 55021cc099d4abef5652d11fef73e72cd170dd71c1b29291c90bfa7e1b0c9f0df4f406b3c174e9aa8f69089edb5e79734a0a216bed20523a2d479046622c02fa
data/NEWS.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # NEWS
2
2
 
3
+ ## 0.9.0: 2014-07-13
4
+
5
+ Now we have TreeView, and many problems are resolved.
6
+
7
+ ### Changes
8
+
9
+ * Improvements
10
+ * Improve scrolling movements.
11
+ * Save CPU and memory for distinction between text and binary.
12
+ * Improve help messages.
13
+ * Remove thumbnail function.
14
+ * pdf: Support multiple pages.
15
+ * Fit a parent widget (PDF, SVG and Video).
16
+ * Support music files.
17
+ * Add key bindings.
18
+ * Introduce Navigator as Gtk::TreeView.
19
+
20
+ * Fixes
21
+ * image: Enable animation for image files such as animated GIF.
22
+ * video: Fix a bug that destroyed object is called.
23
+
3
24
  ## 0.2.1: 2014-05-29
4
25
 
5
26
  ### Changes
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Mireru [![Build Status](https://secure.travis-ci.org/myokoym/mireru.png?branch=master)](http://travis-ci.org/myokoym/mireru)
2
2
 
3
- A file viewer with a focus on flexibility by Ruby/GTK3.
3
+ Mireru is a keyboard friendly file viewer by Ruby/GTK3.
4
4
 
5
- A friend of a keyboard.
5
+ It can handle a variety of file types (Picture, Text, PDF, Video and etc.).
6
6
 
7
7
  ## Requirements
8
8
 
9
- * Ruby/GTK3, Ruby/GtkSourceView3, Ruby/ClutterGTK, Ruby/ClutterGStreamer
10
- , Ruby/Poppler and Ruby/RSVG2 in
9
+ * Ruby/GTK3, Ruby/GtkSourceView3, Ruby/ClutterGTK, Ruby/ClutterGStreamer,
10
+ Ruby/Poppler and Ruby/RSVG2 in
11
11
  [Ruby-GNOME2](http://ruby-gnome2.sourceforge.jp/)
12
12
  * [hexdump](https://github.com/postmodern/hexdump)
13
13
 
@@ -19,28 +19,36 @@ A friend of a keyboard.
19
19
 
20
20
  ### Launch
21
21
 
22
- $ mireru [OPTION]... [FILE]...
22
+ $ mireru [OPTION]... [FILE_OR_DIRECTORY]...
23
23
 
24
- If no argument, then search current directory.
24
+ If no argument, then open the current directory.
25
25
 
26
26
  ### Options
27
27
 
28
- -R, --recursive<br />
29
- recursive search as "**/*"
28
+ -h, --help<br />
29
+ show this help message
30
30
 
31
31
  -f, --font NAME<br />
32
- set font such as "Monospace 16"
32
+ set a font such as "Monospace 16"
33
33
 
34
- ### Keybind
34
+ ### Key bindings
35
35
 
36
36
  #### Common
37
37
 
38
38
  n: next<br />
39
39
  p: prev<br />
40
+ e: expand/collpse<br />
40
41
  r: reload<br />
41
- e: expand path<br />
42
42
  q: quit<br />
43
43
 
44
+ #### Control key mask
45
+
46
+ Ctrl+n: 10 tiles next<br />
47
+ Ctrl+p: 10 tiles prev<br />
48
+ Ctrl+e: expand all/collpse even if cursor on file<br />
49
+ Ctrl+h: move position of partition to left<br />
50
+ Ctrl+l: move position of partition to right<br />
51
+
44
52
  #### Scroll
45
53
 
46
54
  h: left<br />
@@ -48,19 +56,22 @@ j: down<br />
48
56
  k: up<br />
49
57
  l: right<br />
50
58
 
59
+ Shift+h: 100 times left<br />
60
+ Shift+j: 100 times down<br />
61
+ Shift+k: 100 times up<br />
62
+ Shift+l: 100 times right<br />
63
+
64
+ Shift+g: down to bottom<br />
65
+
51
66
  #### Scale
52
67
 
53
68
  +: larger<br />
54
69
  -: smaller<br />
55
70
 
56
- #### Special
57
-
58
- T: thumbnail
59
-
60
71
  #### Image
61
72
 
62
- f: fits window size<br />
63
- o: original size<br />
73
+ f: fit window size<br />
74
+ o: scale to the original size<br />
64
75
 
65
76
  #### Text
66
77
 
@@ -70,6 +81,11 @@ f: change font (at random)<br />
70
81
 
71
82
  space: play/pause<br />
72
83
 
84
+ #### PDF
85
+
86
+ j: next page<br />
87
+ k: prev page<br />
88
+
73
89
  ## License
74
90
 
75
91
  Copyright (c) 2013-2014 Masafumi Yokoyama <myokoym@gmail.com>
@@ -1,8 +1,8 @@
1
1
  require "mireru/version"
2
- require "mireru/container"
3
2
  require "mireru/logger"
4
3
  require "mireru/widget"
5
4
  require "mireru/window"
5
+ require "mireru/navigator"
6
6
 
7
7
  module Mireru
8
8
  end
@@ -1,13 +1,11 @@
1
- require "gtk3"
2
1
  require "mireru/logger"
3
2
  require "mireru/window"
4
- require "mireru/container"
5
3
  require "mireru/version"
6
4
 
7
5
  module Mireru
8
6
  module Command
9
7
  class Mireru
10
- USAGE = "Usage: mireru [OPTION]... [FILE]..."
8
+ USAGE = "Usage: mireru [OPTION]... [FILE_OR_DIRECTORY]..."
11
9
 
12
10
  class << self
13
11
  def run(*arguments)
@@ -31,44 +29,17 @@ module Mireru
31
29
  font = purge_option(arguments, /\A(-f|--font)\z/, true)
32
30
 
33
31
  files = files_from_arguments(arguments)
34
- file_container = ::Mireru::Container.new(files)
35
32
 
36
- if file_container.empty?
37
- write_empty_message
38
- exit(false)
39
- end
40
-
41
- window = ::Mireru::Window.new
33
+ window = ::Mireru::Window.new(files)
42
34
  window.font = font if font
43
- window.add_container(file_container)
44
35
 
45
- Gtk.main
36
+ window.run
46
37
  end
47
38
 
48
39
  private
49
40
  def files_from_arguments(arguments)
50
41
  if arguments.empty?
51
- files = Dir.glob("*")
52
- elsif purge_option(arguments, /\A(-R|--recursive|-d|--deep)\z/)
53
- if arguments.empty?
54
- files = Dir.glob("**/*")
55
- else
56
- files = []
57
- arguments.each do |f|
58
- if File.directory?(f)
59
- files << Dir.glob("#{f}/**/*")
60
- else
61
- files << f
62
- end
63
- end
64
- files.flatten!
65
- end
66
- elsif arguments.all? {|v| File.directory?(v) }
67
- files = []
68
- arguments.each do |f|
69
- files << Dir.glob("#{f}/*")
70
- end
71
- files.flatten!
42
+ files = [Dir.pwd]
72
43
  else
73
44
  files = arguments
74
45
  end
@@ -89,38 +60,59 @@ module Mireru
89
60
  def write_help_message
90
61
  message = <<-EOM
91
62
  #{USAGE}
92
- If no argument, then search current directory.
63
+ If no argument, then open the current directory.
64
+
93
65
  Options:
94
- -R, --recursive
95
- recursive search as "**/*"
66
+ -h, --help
67
+ show this help message
68
+
96
69
  -f, --font NAME
97
- set font such as "Monospace 16"
98
- Keybind:
70
+ set a font such as "Monospace 16"
71
+
72
+ Key bindings:
99
73
  n: next
100
74
  p: prev
75
+ e: expand/collpse
101
76
  r: reload
102
- e: expand path
103
77
  q: quit
104
78
 
79
+ Control key mask:
80
+ Ctrl+n: 10 tiles next
81
+ Ctrl+p: 10 tiles prev
82
+ Ctrl+e: expand all / collpse even if cursor on file
83
+ Ctrl+h: move position of partition to left
84
+ Ctrl+l: move position of partition to right
85
+
105
86
  scroll:
106
87
  h: left
107
88
  j: down
108
89
  k: up
109
90
  l: right
110
91
 
92
+ Shift+h: 100 times left
93
+ Shift+j: 100 times down
94
+ Shift+k: 100 times up
95
+ Shift+l: 100 times right
96
+
97
+ Shift+g: down to bottom
98
+
111
99
  scale:
112
100
  +: larger
113
101
  -: smaller
114
102
 
115
103
  image:
116
- f: fits window size
117
- o: original size
104
+ f: fit window size
105
+ o: scale to the original size
118
106
 
119
107
  text:
120
108
  f: change font (at random)
121
109
 
122
110
  video:
123
111
  space: play/pause
112
+
113
+ PDF:
114
+ j: next page
115
+ k: prev page
124
116
  EOM
125
117
  @logger.info(message)
126
118
  end
@@ -131,20 +123,6 @@ Keybind:
131
123
  EOM
132
124
  @logger.info(message)
133
125
  end
134
-
135
- def write_empty_message
136
- message = <<-EOM
137
- Warning: file not found.
138
- #{USAGE}
139
- If no argument, then search current directory.
140
- Options:
141
- -R, --recursive
142
- recursive search as "**/*"
143
- -f, --font NAME
144
- set font such as "Monospace 16"
145
- EOM
146
- @logger.error(message)
147
- end
148
126
  end
149
127
  end
150
128
  end
@@ -0,0 +1,166 @@
1
+ require "gtk3"
2
+
3
+ module Mireru
4
+ class Navigator < Gtk::ScrolledWindow
5
+ PATH_COLUMN, FILENAME_COLUMN, ICON_COLUMN = 0, 1, 2
6
+
7
+ def initialize(window, files)
8
+ super()
9
+ @window = window
10
+ @files = files
11
+ @dir_iters = {}
12
+ set_policy(:automatic, :automatic)
13
+ set_size_request(200, -1)
14
+ @model = Gtk::TreeStore.new(String, String, Gdk::Pixbuf)
15
+ @tree_view = create_tree(@model)
16
+ add(@tree_view)
17
+ end
18
+
19
+ def next
20
+ @tree_view.move_cursor(Gtk::MovementStep::DISPLAY_LINES, 1)
21
+ end
22
+
23
+ def prev
24
+ @tree_view.move_cursor(Gtk::MovementStep::DISPLAY_LINES, -1)
25
+ end
26
+
27
+ def expand_toggle(open_all=false)
28
+ path = selected_path
29
+ iter = @model.get_iter(path)
30
+ file_path = iter.get_value(PATH_COLUMN)
31
+ if open_all and File.file?(file_path)
32
+ parent = iter.parent
33
+ path = @model.get_path(parent)
34
+ @tree_view.collapse_row(path)
35
+ elsif @tree_view.row_expanded?(path)
36
+ @tree_view.collapse_row(path)
37
+ else
38
+ if open_all
39
+ return unless File.directory?(file_path)
40
+ Dir.glob("#{file_path}/*") do |dir|
41
+ next unless File.directory?(dir)
42
+ child_iter = @dir_iters[dir]
43
+ next unless child_iter
44
+ load_dir(@model, dir, child_iter, true)
45
+ @dir_iters.delete(dir)
46
+ end
47
+ end
48
+ @tree_view.expand_row(path, open_all)
49
+ end
50
+ end
51
+
52
+ def selected_path
53
+ selection = @tree_view.selection
54
+ selected = selection.selected
55
+ @model.get_path(selected)
56
+ end
57
+
58
+ private
59
+ def create_tree(model)
60
+ tree_view = Gtk::TreeView.new
61
+ tree_view.set_model(model)
62
+ tree_view.search_column = FILENAME_COLUMN
63
+ tree_view.enable_search = false
64
+
65
+ selection = tree_view.selection
66
+ selection.set_mode(:browse)
67
+
68
+ @files.each do |file|
69
+ load_file(model, file)
70
+ end
71
+
72
+ column = Gtk::TreeViewColumn.new
73
+ if @files.size == 1
74
+ column.title = File.dirname(@files.first)
75
+ else
76
+ column.title = "Selected Files"
77
+ end
78
+ tree_view.append_column(column)
79
+
80
+ renderer = Gtk::CellRendererPixbuf.new
81
+ renderer.set_fixed_size(*Gtk::IconSize.lookup(:menu))
82
+ column.pack_start(renderer, :expand => false)
83
+ column.add_attribute(renderer, :pixbuf, ICON_COLUMN)
84
+
85
+ renderer = Gtk::CellRendererText.new
86
+ column.pack_start(renderer, :expand => false)
87
+ column.add_attribute(renderer, :text, FILENAME_COLUMN)
88
+
89
+ selection.signal_connect("changed") do |selection|
90
+ apply_changed(selection)
91
+ end
92
+
93
+ tree_view.expand_all
94
+ tree_view
95
+ end
96
+
97
+ def apply_changed(selection)
98
+ iter = selection.selected
99
+ return unless iter
100
+ path = iter.get_value(PATH_COLUMN)
101
+ if File.directory?(path)
102
+ if @dir_iters[path]
103
+ load_dir(@model, path, @dir_iters[path])
104
+ end
105
+ @dir_iters.delete(path)
106
+ end
107
+ return unless File.file?(path)
108
+ @window.title = path
109
+ @window.file = path
110
+ begin
111
+ GLib::Timeout.add(100) do
112
+ if @window.file == path
113
+ begin
114
+ @window.add_from_file(path)
115
+ rescue => e
116
+ $stderr.puts("#{e.class}: #{e.message}")
117
+ $stderr.puts(e.backtrace)
118
+ end
119
+ end
120
+ false
121
+ end
122
+ rescue
123
+ stock = Gtk::Stock::MISSING_IMAGE
124
+ size = :dialog
125
+ pixbuf = Gtk::Image.new.render_icon_pixbuf(stock, size)
126
+ end
127
+ end
128
+
129
+ def load_dir(model, dir, parent=nil, recursive=false)
130
+ Dir.glob("#{File.expand_path(dir)}/*") do |child|
131
+ load_file(model, child, parent, recursive)
132
+ end
133
+ end
134
+
135
+ def load_file(model, file, parent=nil, recursive=false)
136
+ iter = model.append(parent)
137
+ iter.set_value(PATH_COLUMN, file)
138
+ iter.set_value(FILENAME_COLUMN, File.basename(file))
139
+ if File.directory?(file)
140
+ @dir_iters[file] = iter unless recursive
141
+ dir_icon = self.render_icon_pixbuf(Gtk::Stock::DIRECTORY, :menu)
142
+ iter.set_value(ICON_COLUMN, dir_icon)
143
+ load_dir(model, file, iter, recursive) if recursive
144
+ else
145
+ file_icon = select_icon(file)
146
+ iter.set_value(ICON_COLUMN, file_icon)
147
+ end
148
+ # TODO: too slow...
149
+ #icon_width, icon_height = Gtk::IconSize.lookup(:menu)
150
+ #begin
151
+ # pixbuf = Gdk::Pixbuf.new(file_path, icon_width, icon_height)
152
+ #rescue Gdk::PixbufError
153
+ # pixbuf = file_icon
154
+ #end
155
+ #iter.set_value(ICON_COLUMN, pixbuf)
156
+ end
157
+
158
+ def select_icon(file)
159
+ if Widget.video?(file) or Widget.music?(file)
160
+ self.render_icon_pixbuf(Gtk::Stock::CDROM, :menu)
161
+ else
162
+ self.render_icon_pixbuf(Gtk::Stock::FILE, :menu)
163
+ end
164
+ end
165
+ end
166
+ end