keepyourhead 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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,44 @@
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 FileRoot < BaseItemWithXml
22
+ def initialize( file, node )
23
+ super file, node
24
+
25
+ assert self.version == Project::FILE_VERSION
26
+
27
+ end
28
+
29
+ XmlAccessor.addAttribute self, :version, "version", :onItemChange, proc { |item,v| v }
30
+
31
+ xml = XmlAccessorElementList.new self, :collection, /^collection$/,
32
+ proc { |item,node|
33
+ item.objectFromNode(node) {
34
+ Collection.new item.file, node
35
+ }
36
+ }
37
+
38
+ xml.addRead
39
+ xml.addInsert :onItemInsert
40
+ xml.addRemove :onItemRemove
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,116 @@
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 Flashcard < BaseItemWithXml
22
+ XmlAccessor::addElementCData self, :front, "front", :onItemChange, proc { |item,v| v || "" }
23
+ XmlAccessor::addElementCData self, :back, "back", :onItemChange, proc { |item,v| v || "" }
24
+
25
+ XmlAccessor::addAttribute self, :name, "name", :onItemChange, proc { |item,v| v || "" }
26
+ XmlAccessor::addAttribute self, :type, "type", :onItemChange, proc { |item,v| v || "" }
27
+ XmlAccessor::addAttribute self, :style, "style", :onItemChange, proc { |item,v| v || "" }
28
+
29
+ XmlAccessor::addElementText self, :nextCheck, "nextCheck", :onItemChange, proc { |item, v| (v && Time.parse(v)) || (Time.now - 60) }
30
+ XmlAccessor::addElementText self, :level, "level", :onItemChange, proc { |item, v| (v && v.to_i) || 0 }
31
+
32
+ # XmlAccessor::addElementText self, :cacheFilename, "cacheFilename", nil
33
+ # XmlAccessor::addElementText self, :cacheFrontContentHash, "cacheFrontContentHash", nil
34
+ # XmlAccessor::addElementText self, :cacheFrontFileHash, "cacheFrontFileHash", nil
35
+ # XmlAccessor::addElementText self, :cacheBackContentHash, "cacheBackContentHash", nil
36
+
37
+
38
+ # some functions defined on all database entities for iteration
39
+ def collectFlashcards
40
+ [self]
41
+ end
42
+
43
+ def count
44
+ 1
45
+ end
46
+ def countActive
47
+ active? ? 1 : 0
48
+ end
49
+ def countPassive
50
+ active? ? 0 : 1
51
+ end
52
+
53
+ def distribution
54
+ distribution = []
55
+
56
+ distribution[self.level] = 1
57
+
58
+ distribution
59
+ end
60
+
61
+ def removeStatistics
62
+ self.level = 0
63
+ self.nextCheck = Time.new - 60
64
+ end
65
+
66
+
67
+
68
+
69
+ def active?
70
+ nextCheck <= Time.now
71
+ end
72
+
73
+ def content(type, options = {})
74
+ styleInstance = file.style(self.style)
75
+ styleInstance.content(type, self, options)
76
+ end
77
+ def compileImage(type, options = {})
78
+ styleInstance = file.style(self.style)
79
+ compilation = styleInstance.createImage(type, self, options )
80
+ end
81
+
82
+ def collection
83
+ ret = self
84
+ while ret and not ret.kind_of? Collection
85
+ ret = ret.parent
86
+ end
87
+ ret
88
+ end
89
+
90
+ def topic
91
+ parent && parent.class == Topic && parent
92
+ end
93
+ def topicNames
94
+ topics = []
95
+
96
+ n = topic
97
+ while n do
98
+ topics << n.name
99
+ n = n.topic
100
+ end
101
+
102
+ topics = topics.reverse
103
+ topics
104
+ end
105
+
106
+
107
+ def self.createNode( file )
108
+ obj = Flashcard.new file, ::REXML::Element.new("flashcard")
109
+ obj.name = "neue Flashcard"
110
+ obj.style = "latex"
111
+ obj.node
112
+ end
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,40 @@
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 Topic < BaseTopicFlashcardContainer
22
+ def initialize( file, node )
23
+ super file, node
24
+ end
25
+
26
+ XmlAccessor::addAttribute self, :name, "name", :onItemChange
27
+
28
+ def topic
29
+ parent && parent.class == Topic && parent
30
+ end
31
+
32
+ def self.createNode(file)
33
+ obj = Topic.new file, ::REXML::Element.new("topic")
34
+ obj.name = "neues Topic"
35
+ obj.node
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,33 @@
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 Visitor
22
+ def onItemChange(item)
23
+ end
24
+ def onItemRemove(item)
25
+ end
26
+ def onItemInsert(item)
27
+ end
28
+ def onReload()
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,315 @@
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 XmlAccessor
21
+ def xmlAccessorElementCDataRead( name, procRead )
22
+ parent = REXML::XPath.first( node, name )
23
+ ret = parent && parent.children.map{ |c|
24
+ case c
25
+ when REXML::Text
26
+ c.value
27
+ when REXML::CData
28
+ c.value
29
+ else
30
+ nil
31
+ end
32
+ }.compact.join("")
33
+ (procRead && procRead.call(self, ret) ) || ret
34
+ end
35
+
36
+ def xmlAccessorElementCDataWrite( name, notifyEvent, value, procWrite )
37
+ lastValue = (val = REXML::XPath.first( node, name )) && val.cdatas.map{ |cd| cd.value }.join("")
38
+
39
+
40
+ newValue = (procWrite && procWrite.call(self, value)) || value
41
+
42
+ node_ = REXML::XPath.first( node, name )
43
+ node_ ||= @node.add REXML::Element.new(name)
44
+
45
+ if lastValue != newValue then
46
+ node_.delete_at 0 while node_.length > 0
47
+
48
+ node_.add REXML::CData.new(newValue)
49
+
50
+ file.viewersSend notifyEvent, self if notifyEvent
51
+ end
52
+ end
53
+
54
+ def self.addElementCData( _class, functionName, elementName, notifyEvent, procRead = nil, procWrite = nil )
55
+ _class.my_define_method(functionName.to_sym) {
56
+ xmlAccessorElementCDataRead elementName, procRead
57
+ }
58
+ _class.my_define_method( (functionName.to_s + "=").to_sym ) { |value|
59
+ xmlAccessorElementCDataWrite elementName, notifyEvent, value, procWrite
60
+ }
61
+ end
62
+
63
+
64
+
65
+
66
+
67
+
68
+ def xmlAccessorAttributeRead( name, procRead )
69
+ ret = @node.attributes[name]
70
+ (procRead && procRead.call(self, ret) ) || ret
71
+ end
72
+
73
+ def xmlAccessorAttributeWrite( name, notifyEvent, value, procWrite )
74
+ value = (procWrite && procWrite.call(self, value)) || value
75
+
76
+ if @node.attributes[name] != value then
77
+ @node.attributes[name] = value
78
+
79
+ file.viewersSend notifyEvent, self if notifyEvent
80
+ end
81
+ end
82
+
83
+ def self.addAttribute( _class, functionName, elementName, notifyEvent, procRead = nil, procWrite = nil )
84
+ _class.my_define_method(functionName.to_sym) {
85
+ xmlAccessorAttributeRead elementName, procRead
86
+ }
87
+ _class.my_define_method( (functionName.to_s + "=").to_sym ) { |value|
88
+ xmlAccessorAttributeWrite elementName, notifyEvent, value, procWrite
89
+ }
90
+ end
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+ def xmlAccessorElementTextRead( name, procRead )
99
+ n = REXML::XPath.first( node, name )
100
+ ret = n && n.text
101
+
102
+ (procRead && procRead.call(self,ret) ) || ret
103
+ end
104
+
105
+ def xmlAccessorElementTextWrite( name, notifyEvent, value, procWrite )
106
+ value = (procWrite && procWrite.call(self,value)) || value
107
+
108
+ n = REXML::XPath.first( node, name )
109
+
110
+ if not n or n.text != value then
111
+ n ||= node.add REXML::Element.new(name)
112
+ n.text=value
113
+
114
+ file.viewersSend notifyEvent, self if notifyEvent
115
+ end
116
+ end
117
+
118
+ def self.addElementText( _class, functionName, elementName, notifyEvent, procRead = nil, procWrite = nil )
119
+ _class.my_define_method(functionName.to_sym) {
120
+ xmlAccessorElementTextRead elementName, procRead
121
+ }
122
+ _class.my_define_method( (functionName.to_s + "=").to_sym ) { |value|
123
+ xmlAccessorElementTextWrite elementName, notifyEvent, value, procWrite
124
+ }
125
+ end
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+ def xmlAccessorElementListRead( name, procRead )
134
+ ret = @node.elements.select { |node| node.name =~ name }
135
+ ret.map! { |node|
136
+ (procRead && procRead.call(self,node) ) || node.name
137
+ }
138
+ end
139
+
140
+ def xmlAccessorElementListNext( name, procRead, other )
141
+ assert other.parent == self
142
+
143
+ ret = other.node
144
+ begin
145
+ ret = ret.next_element
146
+ end while (ret and not ret.name =~ name)
147
+
148
+ return nil unless ret
149
+
150
+ (procRead && procRead.call(self,ret) ) || ret.name
151
+ end
152
+
153
+ def xmlAccessorElementListPrevious( name, procRead, other )
154
+ assert other.parent == self
155
+
156
+ ret = other.node
157
+ begin
158
+ ret = ret.previous_element
159
+ end while ret and not ret.name =~ name
160
+
161
+ return nil unless ret
162
+
163
+ (procRead && procRead.call(self,ret) ) || ret.name
164
+ end
165
+
166
+ def xmlAccessorElementListRemove( name, notifyEvent, item )
167
+ assert item.node.name =~ name
168
+ assert item.parent == self
169
+
170
+ file.viewersSend notifyEvent, item if notifyEvent
171
+
172
+ #node.delete_element item.node
173
+ item.node.remove
174
+
175
+ item.node
176
+ end
177
+
178
+ def xmlAccessorElementListInsertFirst( name, notifyEvent, procRead, node )
179
+ assert node.kind_of?(REXML::Element)
180
+ assert node.name =~ name
181
+
182
+ if self.node[0] then
183
+ self.node.insert_before self.node[0], node
184
+ else
185
+ self.node.add node
186
+ end
187
+
188
+ ret = (procRead && procRead.call(self,node) ) || node.name
189
+
190
+ file.viewersSend notifyEvent, ret if notifyEvent
191
+
192
+ ret
193
+ end
194
+
195
+ def xmlAccessorElementListInsertLast( name, notifyEvent, procRead, node )
196
+ assert node.kind_of?(REXML::Element)
197
+ assert node.name =~ name
198
+
199
+ self.node.add node
200
+
201
+ ret = (procRead && procRead.call(self,node) ) || node.name
202
+
203
+ file.viewersSend notifyEvent, ret if notifyEvent
204
+
205
+ ret
206
+ end
207
+
208
+ def xmlAccessorElementListInsertBefore( name, notifyEvent, procRead, node, other )
209
+ assert node.kind_of?(REXML::Element)
210
+ assert node.name =~ name
211
+ assert other
212
+
213
+ assert other.parent == self
214
+ other.node.parent.insert_before other.node, node
215
+ # other.node.previous_sibling = node
216
+
217
+ ret = (procRead && procRead.call(self,node) ) || node.name
218
+
219
+ file.viewersSend notifyEvent, ret if notifyEvent
220
+
221
+ ret
222
+ end
223
+
224
+ def xmlAccessorElementListInsertAfter( name, notifyEvent, procRead, node, other )
225
+ assert node.kind_of?(REXML::Element)
226
+ assert node.name =~ name
227
+ assert other
228
+
229
+ assert other.parent == self
230
+ other.node.parent.insert_after other.node, node
231
+ # other.node.next_sibling = node
232
+
233
+ ret = (procRead && procRead.call(self,node) ) || node.name
234
+
235
+ file.viewersSend notifyEvent, ret if notifyEvent
236
+
237
+ ret
238
+ end
239
+
240
+ def xmlAccessorElementListCreate( name, notifyEvent, procCreate )
241
+ =begin
242
+ node = REXML::Element.new name
243
+
244
+ if self.node[0] then
245
+ self.node.insert_before self.node[0], node
246
+ else
247
+ self.node.add node
248
+ end
249
+ =end
250
+ # node = self.node.add_element name
251
+ node = self.node.add REXML::Element.new(name)
252
+
253
+ ret = (procCreate && procCreate.call(self,node)) || node.name
254
+
255
+ file.viewersSend notifyEvent, ret if notifyEvent
256
+
257
+ ret
258
+ end
259
+
260
+ class XmlAccessorElementList
261
+ attr_reader :_class, :functionName, :elementRegExp, :procRead
262
+ def initialize(_class, functionName, elementRegExp, procRead )
263
+ @_class, @functionName, @elementRegExp, @procRead =
264
+ _class, functionName, elementRegExp, procRead
265
+ end
266
+ def _addRead(elementRegExp,procRead)
267
+ _class.my_define_method((functionName.to_s + "s").to_sym) {
268
+ xmlAccessorElementListRead elementRegExp, procRead
269
+ }
270
+ _class.my_define_method((functionName.to_s + "Next").to_sym) { |other|
271
+ xmlAccessorElementListNext elementRegExp, procRead, other
272
+ }
273
+ _class.my_define_method((functionName.to_s + "Previous").to_sym) { |other|
274
+ xmlAccessorElementListPrevious elementRegExp, procRead, other
275
+ }
276
+ end
277
+ def addRead
278
+ _addRead(elementRegExp, procRead)
279
+ end
280
+ def _addRemove(elementRegExp, notifyEvent)
281
+ _class.my_define_method((functionName.to_s + "Remove").to_sym) { |item|
282
+ xmlAccessorElementListRemove elementRegExp, notifyEvent, item
283
+ }
284
+ end
285
+ def addRemove(notifyEvent)
286
+ _addRemove(elementRegExp, notifyEvent)
287
+ end
288
+ def _addInsert(elementRegExp, procRead, notifyEvent)
289
+ _class.my_define_method((functionName.to_s + "InsertFirst").to_sym) { |node|
290
+ xmlAccessorElementListInsertFirst elementRegExp, notifyEvent, procRead, node
291
+ }
292
+ _class.my_define_method((functionName.to_s + "InsertLast").to_sym) { |node|
293
+ xmlAccessorElementListInsertLast elementRegExp, notifyEvent, procRead, node
294
+ }
295
+ _class.my_define_method((functionName.to_s + "InsertBefore").to_sym) { |node,other|
296
+ xmlAccessorElementListInsertBefore elementRegExp, notifyEvent, procRead, node, other
297
+ }
298
+ _class.my_define_method((functionName.to_s + "InsertAfter").to_sym) { |node,other|
299
+ xmlAccessorElementListInsertAfter elementRegExp, notifyEvent, procRead, node, other
300
+ }
301
+ end
302
+ def addInsert(notifyEvent)
303
+ _addInsert(elementRegExp, procRead, notifyEvent)
304
+ end
305
+ def addCreate(functionName, elementName, notifyEvent, procCreate)
306
+ _class.my_define_method((functionName.to_s + "Create").to_sym) { ||
307
+ xmlAccessorElementListCreate elementName, notifyEvent, procCreate
308
+ }
309
+ end
310
+ end
311
+ end
312
+
313
+
314
+ end
315
+