keepyourhead 0.2.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.
Files changed (47) hide show
  1. data/COPYING.txt +674 -0
  2. data/LICENSE.rdoc +20 -0
  3. data/README.rdoc +3 -0
  4. data/bin/keepyourhead +6 -0
  5. data/data/glade/DialogEditLatex.glade +180 -0
  6. data/data/glade/DialogEditText.glade +66 -0
  7. data/data/glade/DialogTrainStart.glade +101 -0
  8. data/data/glade/WindowEdit.glade +1419 -0
  9. data/data/glade/WindowTrain.glade +271 -0
  10. data/data/images/error_back.png +0 -0
  11. data/data/images/error_front.png +0 -0
  12. data/data/images/loading_back.png +0 -0
  13. data/data/images/loading_front.png +0 -0
  14. data/lib/Keepyourhead.rb +62 -0
  15. data/lib/Keepyourhead/Application.rb +94 -0
  16. data/lib/Keepyourhead/Cache.rb +233 -0
  17. data/lib/Keepyourhead/Compilation.rb +38 -0
  18. data/lib/Keepyourhead/Images.rb +62 -0
  19. data/lib/Keepyourhead/Preferences.rb +52 -0
  20. data/lib/Keepyourhead/Requirements.rb +72 -0
  21. data/lib/Keepyourhead/Resources.rb +45 -0
  22. data/lib/Keepyourhead/Training.rb +132 -0
  23. data/lib/Keepyourhead/Utils.rb +97 -0
  24. data/lib/Keepyourhead/Version.rb +43 -0
  25. data/lib/Keepyourhead/database/Base.rb +77 -0
  26. data/lib/Keepyourhead/database/BaseStatistic.rb +63 -0
  27. data/lib/Keepyourhead/database/BaseTopicFlashcardContainer.rb +43 -0
  28. data/lib/Keepyourhead/database/Collection.rb +43 -0
  29. data/lib/Keepyourhead/database/Database.rb +139 -0
  30. data/lib/Keepyourhead/database/File.rb +224 -0
  31. data/lib/Keepyourhead/database/FileRoot.rb +44 -0
  32. data/lib/Keepyourhead/database/Flashcard.rb +116 -0
  33. data/lib/Keepyourhead/database/Topic.rb +40 -0
  34. data/lib/Keepyourhead/database/Visitor.rb +33 -0
  35. data/lib/Keepyourhead/database/XmlAccessor.rb +315 -0
  36. data/lib/Keepyourhead/gui/Action.rb +91 -0
  37. data/lib/Keepyourhead/gui/DialogEditLatex.rb +132 -0
  38. data/lib/Keepyourhead/gui/DialogEditText.rb +104 -0
  39. data/lib/Keepyourhead/gui/DialogTrainStart.rb +63 -0
  40. data/lib/Keepyourhead/gui/FlashcardViewController.rb +112 -0
  41. data/lib/Keepyourhead/gui/WindowEdit.rb +469 -0
  42. data/lib/Keepyourhead/gui/WindowEditActions.rb +440 -0
  43. data/lib/Keepyourhead/gui/WindowEditAdapters.rb +329 -0
  44. data/lib/Keepyourhead/gui/WindowTrain.rb +167 -0
  45. data/lib/Keepyourhead/style/Style.rb +48 -0
  46. data/lib/Keepyourhead/style/StyleLatex.rb +235 -0
  47. metadata +100 -0
@@ -0,0 +1,167 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+
20
+ module KeepYourHead
21
+ class WindowQuestion
22
+ attr_reader :parent
23
+ attr_reader :training
24
+
25
+ attr_reader :window
26
+
27
+ Widgets = [
28
+ "imageFront", "imageBack", "notebook", "scrolledwindowNotebook",
29
+ "hboxFront", "hboxBack", "hscaleFront", "hscaleBack",
30
+ "progressbarFlashcards", "progressbarTime",
31
+ ]
32
+
33
+ def initialize( parent, training )
34
+ @parent = parent
35
+ self.parent.widget.hide if self.parent
36
+
37
+ @updateImagesMutex = Mutex.new
38
+ @glade = GladeXML.new(Resources::system("glade/WindowTrain.glade")) { |handler| method(handler) }
39
+
40
+ Widgets.each { |name|
41
+ widget = @glade.get_widget(name)
42
+ assert widget
43
+ eval("@#{name} = widget")
44
+ }
45
+ @window = @glade.get_widget("window_train")
46
+ # @window.maximize
47
+
48
+ @training = training
49
+
50
+
51
+ @flashcardViewControllerFront = FlashcardViewController.new @imageFront, @hscaleFront, @hboxFront
52
+ @flashcardViewControllerBack = FlashcardViewController.new @imageBack, @hscaleBack, @hboxBack
53
+
54
+ @running = true
55
+ Gtk.timeout_add(10000) {
56
+ if @running then
57
+ @progressbarTime.fraction = @training.progressTime
58
+
59
+ true
60
+ else
61
+ false
62
+ end
63
+ }
64
+
65
+ @window.show
66
+ updateView
67
+ end
68
+
69
+ def onHelp
70
+ @notebook.page = (@notebook.page + 1).modulo 2
71
+ end
72
+
73
+ def onKnown
74
+ self.training.onKnown
75
+ updateView
76
+ end
77
+
78
+ def onUnknown
79
+ self.training.onUnknown
80
+ updateView
81
+ end
82
+
83
+ def onEdit
84
+ end
85
+
86
+ def onDestroy
87
+ @running = false
88
+
89
+ @training.close
90
+
91
+ message = <<END
92
+ Zeit: $(time.used) min / $(time.max) min
93
+ Karteikarten gefragt: $(flashcards.asked)
94
+ gewußt/nicht gewußt: $(flashcards.known) / $(flashcards.unknown)
95
+ END
96
+
97
+ message = message.clone
98
+ message.gsub!( "$(time.used)", (training.timeUsed / 60.0).to_i.to_s )
99
+ message.gsub!( "$(time.max)", (training.timeMax / 60.0).to_i.to_s )
100
+ message.gsub!( "$(flashcards.asked)", training.flashcardsAsked.length.to_s )
101
+ message.gsub!( "$(flashcards.known)", training.flashcardsKnown.length.to_s )
102
+ message.gsub!( "$(flashcards.unknown)", training.flashcardsUnknown.length.to_s )
103
+
104
+ dialog = Gtk::MessageDialog.new(
105
+ @window, Gtk::Dialog::MODAL, Gtk::MessageDialog::INFO,
106
+ Gtk::MessageDialog::BUTTONS_OK, message )
107
+ dialog.title = "Training beendet"
108
+ response = dialog.run
109
+ dialog.destroy
110
+
111
+ self.parent.widget.show if self.parent
112
+ end
113
+
114
+ def onQuit
115
+ @window.destroy
116
+ end
117
+
118
+ def flashcard
119
+ self.training.flashcard
120
+ end
121
+
122
+ Timeout = (1000 * 0.2).to_i
123
+
124
+ def updateView
125
+ if flashcard then
126
+ @notebook.page = 0
127
+
128
+ # @scrolledwindowNotebook.width_request = (ImageWidth * 1.1).to_i
129
+ @progressbarFlashcards.fraction = @training.progressFlashcards
130
+
131
+ Thread.new {
132
+ begin
133
+ $cache.getCacheItem( flashcard, Database::FRONT )
134
+ $cache.getCacheItem( flashcard, Database::BACK )
135
+ rescue
136
+ puts $!.backtrace, $!
137
+ end
138
+ }
139
+
140
+ Gtk.timeout_add( Timeout ) {
141
+ ret = true
142
+ if @running then
143
+ [Database::FRONT, Database::BACK].each { |type|
144
+ $cache.hasCacheItem( flashcard, type ) { |cacheItem|
145
+ ret &&= cacheItem
146
+
147
+ filenames = Images.fromCacheItem type, cacheItem
148
+
149
+ case type
150
+ when Database::FRONT
151
+ @flashcardViewControllerFront.filenames = filenames
152
+ when Database::BACK
153
+ @flashcardViewControllerBack.filenames = filenames
154
+ end
155
+ }
156
+ }
157
+ end
158
+ not ret
159
+ }
160
+ else
161
+ @window.destroy
162
+ end
163
+ end
164
+ end
165
+
166
+
167
+ end
@@ -0,0 +1,48 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ (FRONT,BACK)=(1..2).to_a
22
+
23
+ class Style
24
+ def initialize(file)
25
+ end
26
+
27
+ def createImage( type, flashcard, width, previewCode )
28
+ end
29
+
30
+ def content( type, flashcard, width, previewCode )
31
+ end
32
+
33
+
34
+
35
+
36
+ def self.addStyle( s )
37
+ $styles ||= {}
38
+ $styles[s.Name] = s
39
+ end
40
+
41
+ def self.getStyle(name)
42
+ $styles[name]
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,235 @@
1
+ # Copyright 2008 Burghard Oliver
2
+ #
3
+ # This file is part of KeepYourHead.
4
+ #
5
+ # KeepYourHead is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # KeepYourHead is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with KeepYourHead. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ module KeepYourHead
20
+ module Database
21
+ class StyleLatex < Style
22
+ WidthInCm = 20
23
+
24
+
25
+ def self.Name
26
+ "latex"
27
+ end
28
+
29
+ def initialize( file )
30
+ end
31
+
32
+ def createImage(type, flashcard, options = {})
33
+ latex = latex_code( type, flashcard, options )
34
+
35
+ compileLatex ::File.dirname(flashcard.file.filename), latex, options
36
+ end
37
+
38
+ def content(type,flashcard, options = {})
39
+ latex_code( type, flashcard, options )
40
+ end
41
+
42
+
43
+
44
+
45
+ def latex_code( type, flashcard, options = {} )
46
+ previewCode = options[:previewCode]
47
+ width = options[:width] || Gdk::Screen.default.width || 10
48
+
49
+ assert( type == FRONT || type == BACK )
50
+ ret = case type
51
+ when FRONT
52
+ FrontScheme
53
+ when BACK
54
+ BackScheme
55
+ end.clone
56
+
57
+ topics = flashcard.topicNames
58
+
59
+ contentFront = flashcard.front
60
+ contentFront ||= topics.last
61
+ contentBack = flashcard.back
62
+
63
+ if previewCode then
64
+ case type
65
+ when FRONT
66
+ contentFront = previewCode
67
+ when BACK
68
+ contentBack = previewCode
69
+ end
70
+ end
71
+
72
+ ret.gsub!( "$(widthInCm)", WidthInCm.to_s )
73
+
74
+ ret.gsub!( "$(width)", width.to_s )
75
+ ret.gsub!( "$(header)", flashcard.collection.latexHeader || "" )
76
+ ret.gsub!( "$(type)", flashcard.type || "" )
77
+ ret.gsub!( "$(name)", flashcard.name || "" )
78
+ ret.gsub!( "$(content_front)", contentFront || "" )
79
+ ret.gsub!( "$(content_back)", contentBack || "" )
80
+ ret.gsub!( "$(topics)", topics.join(".") )
81
+ ret.gsub!( "$(prepend)", flashcard.collection.latexPrepend || "" )
82
+ ret.gsub!( "$(append)", flashcard.collection.latexAppend || "" )
83
+
84
+
85
+ ret
86
+ end
87
+
88
+ def compileLatex(baseDirectory, content_latex, options )
89
+ width = options[:width] || Gdk::Screen.default.width || 10
90
+
91
+
92
+ baseDirectory = ::File.expand_path baseDirectory
93
+
94
+ directory = Resources::createWorkingDirectory
95
+ compilation = nil
96
+
97
+ success = true
98
+
99
+ filename_tex = "flashcard.tex"
100
+ filename_output = "output.txt"
101
+ filename_tex = ::File.expand_path( filename_tex, directory )
102
+ filename_output = ::File.expand_path( filename_output, directory )
103
+
104
+ file_tex = ::File.new(filename_tex, "w")
105
+ file_tex << content_latex
106
+ file_tex.close
107
+
108
+ filename_png = 'flashcard_%d.png'
109
+ filename_png = ::File.expand_path filename_png, directory
110
+
111
+
112
+ sub_id = fork { # fork because of use of FileUtils.cd and concurrency
113
+ success = true
114
+ begin
115
+ Process.setpriority(Process::PRIO_PROCESS, 0, 19)
116
+
117
+ FileUtils.cd( directory ) do |dir|
118
+
119
+ # latex execution
120
+ FileUtils.cd( baseDirectory ) {
121
+ system( "pdflatex -output-directory='#{directory}' -interaction nonstopmode '#{filename_tex}' >/dev/null")
122
+ success &&= system( "pdflatex -output-directory='#{directory}' -interaction nonstopmode -halt-on-error '#{filename_tex}' 2>&1 >#{filename_output}")
123
+ }
124
+
125
+ # ghostscript execution
126
+ dpi = (width / (WidthInCm / 2.54)).to_i
127
+
128
+ success &&= system( "gs -dSAFER -dBATCH -dNOPAUSE -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=png16m -sOutputFile='#{filename_png}' -r#{dpi} flashcard.pdf >> #{filename_output}")
129
+ end
130
+ rescue
131
+ print $!, $!.backtrace, "---"
132
+ success = false
133
+ end
134
+
135
+ exit! success ? 1 : 0
136
+ }
137
+
138
+ pid, status = Process.wait2 sub_id
139
+ success &&= (status.exitstatus == 1)
140
+
141
+ filenames = []
142
+ i = 0
143
+ loop do
144
+ filename = filename_png.sub( '%d', i.to_s )
145
+ if ::File.exist? filename then
146
+ filenames << filename
147
+ else
148
+ break if i > 5
149
+ end
150
+
151
+ i += 1
152
+ end
153
+
154
+ file_output = ::File.new( filename_output, "r" )
155
+ output = file_output.readlines.join("")
156
+ ::File.delete filename_output
157
+
158
+ compilation = Compilation.new content_latex, success, output, directory, filenames
159
+
160
+ if not compilation.success then
161
+ compilation.remove
162
+ end
163
+
164
+ compilation
165
+ end
166
+
167
+ private
168
+
169
+ FrontScheme = <<-'END'
170
+ %type: front
171
+ %width: $(width)
172
+
173
+ \documentclass[12pt]{article}
174
+
175
+ \usepackage[papersize={$(widthInCm)cm,5cm},ignoreheadfoot,margin=0.5cm,hmargin=3cm]{geometry}
176
+
177
+ \pagestyle{empty} %empty - no page numbers ....
178
+
179
+ $(header)
180
+
181
+ \begin{document}
182
+
183
+ \begin{flushright} $(type)\end{flushright}
184
+
185
+ \vspace*{\fill}
186
+
187
+ \begin{center}
188
+ $(name)
189
+
190
+ $(content_front)
191
+ \end{center}
192
+
193
+ \vspace*{\fill}
194
+
195
+ \begin{flushleft}
196
+ $(topics)
197
+ \end{flushleft}
198
+
199
+ \end{document}
200
+ END
201
+
202
+ BackScheme = <<-'END'
203
+ %type: back
204
+ %width: $(width)
205
+
206
+ \documentclass[12pt]{article}
207
+
208
+ \usepackage[papersize={$(widthInCm)cm,10cm},ignoreheadfoot,margin=0.5cm]{geometry}
209
+
210
+ \pagestyle{empty} %empty - no page numbers ....
211
+
212
+ $(header)
213
+
214
+ \begin{document}
215
+
216
+ \vspace*{\fill}
217
+
218
+ $(prepend)
219
+ $(content_back)
220
+ $(append)
221
+
222
+ \vspace*{\fill}
223
+
224
+ \end{document}
225
+ END
226
+
227
+ end
228
+
229
+ Style.addStyle( StyleLatex )
230
+ end
231
+
232
+
233
+
234
+
235
+ end