Class: Studium::GUI::UniversalWidgets::CurriculumViewer

Inherits:
UniversalWidgets::Base
  • Object
show all
Includes:
UniversalWidgets::BaseModule
Defined in:
lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb

Overview

Studium::GUI::UniversalWidgets::CurriculumViewer

Constant Summary collapse

TITLE =
#

TITLE

#
'Curriculum Viewer'
WIDTH =
#

WIDTH

#
'35% or minimum 1400px'
HEIGHT =
#

HEIGHT

#
'35% or minimum 1200px'
USE_THIS_FONT =
#

USE_THIS_FONT

#
'Sans 18'
SMALLER_FONT =
#

SMALLER_FONT

#
'Sans 15'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(commandline_arguments = nil, run_already = true) ⇒ CurriculumViewer

#

initialize

#


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 57

def initialize(
    commandline_arguments = nil,
    run_already           = true
  )
  # ======================================================================= #
  # We first have to determine the GUI that is to be used, even before
  # calling reset(). The reason is that this will also require some
  # files, such as the Gdk namespace, which may be used by the GUI
  # related parts for ruby-gtk3, for instance.
  # ======================================================================= #
  determine_the_GUI_to_be_used(commandline_arguments)
  reset
  set_commandline_arguments(
    commandline_arguments
  )
  run if run_already
end

Class Method Details

.[](i = ARGV) ⇒ Object

#

Studium::GUI::UniversalWidgets::CurriculumViewer[]

#


541
542
543
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 541

def self.[](i = ARGV)
  new(i)
end

.run(i = ARGV) ⇒ Object

#

Studium::GUI::Gtk::CurriculumViewer.run

#


506
507
508
509
510
511
512
513
514
515
516
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 506

def self.run(
    i = ARGV
  )
  require 'gtk_paradise/run'
  _ = ::Studium::GUI::Gtk::CurriculumViewer.new(i)
  r = ::Gtk.run
  r << _
  r.automatic_size_then_automatic_title
  r.show_all
  r.top_left_then_run
end

Instance Method Details

#connect_the_skeletonObject

#

connect_the_skeleton (connect tag)

#


521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 521

def connect_the_skeleton
  abort_on_exception
  
  hpane = draggable_hpane(
    @vbox,
    return_widget_on_the_bottom_holding_statistical_information_about_this_curriculum
  )
  hpane.position = 900

  r = create_window_or_runner(hpane, width?, height?, title?)

  r.top_left
  r.enable_quick_exit
  r.set_default_size(width?, height?)
  run_main
end

#create_bold_cell_rendererObject

#

create_bold_cell_renderer

#


157
158
159
160
161
162
163
164
165
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 157

def create_bold_cell_renderer
  @bold_renderer = cell_renderer_text
  @bold_renderer.editable = false
  @bold_renderer.set_property('background', 'white')
  @bold_renderer.set_cell_background('darkblue') # This makes the blue border.
  @bold_renderer.set_markup(
    '<span weight="bold">'+@bold_renderer.text.to_s+'</span>'
  )
end

#create_cell_renderersObject

#

create_cell_renderers

This creates the default cell-renderer used.

#


143
144
145
146
147
148
149
150
151
152
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 143

def create_cell_renderers
  @renderer = cell_renderer_text
  @renderer.editable = false # It is better to not allow editing.
  @renderer.set_property('background', 'white')
  @renderer.set_cell_background('darkblue') # This makes the blue border.
  @renderer_green = cell_renderer_text
  @renderer_green.editable = true
  @renderer_green.set_property('foreground','darkgreen')
  create_bold_cell_renderer
end

#create_entriesObject

#

create_entries (entries tag, entry tag)

#


123
124
125
126
127
128
129
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 123

def create_entries
  @entry_n_ECTS_in_total = create_entry('')
  @entry_n_ECTS_in_total.do_center
  @entry_n_ECTS_in_total.bblack1
  @entry_n_ECTS_in_total.very_light_yellowish_background
  @entry_n_ECTS_in_total.make_bold
end

#create_the_menuObject

#

create_the_menu

This is the toplevel menubar.

#


193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 193

def create_the_menu
  @menu_bar = create_menu_bar
  filemenu = create_menu
  # ======================================================================= #
  # === 1) First menu drop-down interface
  # ======================================================================= #
  filem1 = create_menu_item('File') {{ submenu: filemenu }}
  # ======================================================================= #
  # === Add the 'Show all URLs' entry next:
  # ======================================================================= #
  show_all_URLs = create_menu_item('Show all URLs to the radio station')
  show_all_URLs.on_activate {
    do_show_all_URLs
  }
  filemenu << show_all_URLs
  # ======================================================================= #
  # === Add the 'Reset the Widget' entry next:
  # ======================================================================= #
  reset_the_widget = create_menu_item('Reset the widget')
  reset_the_widget.hint = 'Clicking on this item will reset '\
    'the main widget to its initial state, as if you would '\
    'have just started this application.'
  reset_the_widget.on_activate {
    do_reset_the_widget
  }
  filemenu << reset_the_widget
  filemenu.append_separator
  # ======================================================================= #
  # === Add the 'Exit' entry next:
  # ======================================================================= #
  exit = create_menu_item('Exit') { :on_activate_quit }
  filemenu << exit
  # ======================================================================= #
  # === 2) Second menu drop-down interface
  # ======================================================================= #
  filemenu2 = create_menu
  filem2 = create_menu_item('Not yet in use') {{ submenu: filemenu2 }}
  # ======================================================================= #
  # === Add the 'Shall the stream be captured' entry next:
  # ======================================================================= #
  yes = ::Gtk::RadioMenuItem.new(nil, 'Yes')
  yes.on_activate { @capture_the_stream = true }
  no  = ::Gtk::RadioMenuItem.new(yes, 'No')
  no.on_activate  { @capture_the_stream = false }
  filemenu2 << yes
  filemenu2 << no
  # ======================================================================= #
  # === 3) The info widget
  # ======================================================================= #
  filemenu3 = create_menu
  filem3 = create_menu_item('Info') {{ submenu: filemenu3 }}
  # ======================================================================= #
  # === Add the 'Shall the stream be captured' entry next:
  # ======================================================================= #
  # show_more_info = gtk_menu_item('Show more info about this widget')
  # show_more_info.on_activate { do_show_more_info_about_this_widget }
  # filemenu3 << show_more_info
  # ======================================================================= #
  # Next, add the file-menu parts to the menu bar.
  # ======================================================================= #
  @menu_bar.add_these(filem1, filem2, filem3)
end

#create_the_skeletonObject

#

create_the_skeleton (create tag, skeleton tag)

#


346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 346

def create_the_skeleton
  create_entries
  create_the_menu
  create_cell_renderers
  # ======================================================================= #
  # The relevant entries should be:
  #
  #   (1) the LVA-ID of the lecture at hand
  #   (2) name of the lecture at hand
  #   (3) number of ECTS points
  #   (4) the given semester
  #   (5) already solved or not (Boolean)
  #
  # ======================================================================= #
  @list_store = ::Gtk::ListStore.new(
    String, String, String, String, String # Don't forget to sync this here.
  )
  # ======================================================================= #
  # Obtain the dataset from the curriculum-file.
  # ======================================================================= #
  bachelor_vektor_dataset = ::Studium.read_dataset_from_a_curriculum_file(
    @use_this_curriculum, :remove_comments_and_title
  )
  main_dataset = main_dataset?
  bachelor_vektor_dataset.each {|this_entry|
    this_entry = this_entry.dup if this_entry.frozen?
    this_entry.squeeze!(' ')
    if main_dataset.has_key? this_entry
      pointer        = main_dataset[this_entry]
      n_ects         = pointer[:ects].to_s.rjust(8)
      which_semester = pointer[:semester].to_s
      iter = @list_store.append
      splitted = this_entry.split(' ')
      lva_id   = splitted.first
      raw_name_of_the_lecture = splitted[1 .. -1].join(' ')
      already_solved = pointer[:already_solved]
      if already_solved
        already_solved_or_not = 'Yes'
      else
        already_solved_or_not = 'No'
      end
      iter.set_value(0, lva_id)
      iter.set_value(1, raw_name_of_the_lecture)
      iter.set_value(2, n_ects)
      iter.set_value(3, which_semester)
      iter.set_value(4, already_solved_or_not)
    else
      e 'The dataset does not contain the following key: '+
        ::Colours.steelblue(this_entry.to_s)
    end
  }
  create_the_tree_view
  # Next follows the top-label:
  label = create_label(
            ::Studium.return_title_from_this_curriculum_file(
              @use_this_curriculum
            )
          )
  label.make_bold
  # ======================================================================= #
  # === Add a scrolled window next:
  # ======================================================================= #
  scrolled_window = create_scrolled_window {{ use_this_widget: @tree_view }}
  scrolled_window.always_show_the_scrollbars
  scrolled_window.set_size_request(700, 800)
  @vbox = create_vbox
  @vbox.minimal(label, 0)
  combo_box = dropdown_box_text(
    ::Studium.array_available_curricula
  )
  combo_box.active = 9
  combo_box.bblack2
  combo_box.make_bold
  # React on the combo-box being changed:
  # combo_box.signal_connect(:changed) {
  #   if combo_box.active_iter
  #     e "#{combo_box.active_iter[0]}"
  #   end
  # }
  mini_hbox_containing_the_combo_box = create_hbox
  mini_hbox_containing_the_combo_box.maximal(combo_box)
  # The update-button is created next:
  button_update = button('_Update', self, :use_mnemonics) {
    update_the_tree_view_with_this_curriculum(combo_box.active_iter[0])
  }
  button_update.bblack1
  button_update.pad4px
  button_update.hint = ' Update the <b>curriculum info</b> below. '
  button_update.on_hover {{
    colour: :lightgreen
  }}
  button_update.modify_background :normal, :steelblue
  mini_hbox_containing_the_combo_box.minimal(button_update)
  enable_custom_sorting_for_the_main_list_store
  # ======================================================================= #
  # Next, add the elements into a vbox.
  # ======================================================================= #
  @vbox.minimal(@menu_bar, 0)
  @vbox.minimal(mini_hbox_containing_the_combo_box, 0)
  @vbox.maximal(scrolled_window, 0)
end

#create_the_tree_viewObject

#

create_the_tree_view

#


259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 259

def create_the_tree_view
  # ======================================================================= #
  # === @tree_view
  #
  # Build up our main tree-view widget next.
  # ======================================================================= #
  @tree_view = create_tree_view(@list_store) { :clickable_headers }
  @tree_view.hadjustment = ::Gtk::Adjustment.new(0.0, 0.0, 105.0, 0.2, 1.0, 1.0)
  @tree_view.enable_search = true
  @tree_view.make_reorderable
  @tree_view.the_header_can_be_resized
  @tree_view.all_are_sortable
  @tree_view.do_not_allow_editing
  # ======================================================================= #
  # Fill the tree-view widget with relevant data.
  # ======================================================================= #
  @tree_view.append('LVA-ID',              @renderer,       text: 0)
  @tree_view.append('Name of the lecture', @bold_renderer,  text: 1)
  @tree_view.append('n ECTS',              @renderer,       text: 2)
  @tree_view.append('semester',            @renderer,       text: 3)
  @tree_view.append('already solved?',     @renderer_green, text: 4)
  @tree_view.signal_connect(:button_press_event) { |widget, event|
    type = event.event_type
    case type.name
    when '2button_press'.to_sym,'GDK_2BUTTON_PRESS'
      # =================================================================== #
      # double-click event is handled here:
      # =================================================================== #
      selection = widget.selection.selected
      lva_id              = selection[0]
      name_of_the_lecture = selection[1]
      # =================================================================== #
      # This is triggered when the user clicks on the column.
      # =================================================================== #
      e steelblue(name_of_the_lecture)
      lva_id_and_name_of_the_lecture = "#{lva_id} #{name_of_the_lecture}"
      remote_URL = @dataset_from_the_file_lecture_information[
        lva_id_and_name_of_the_lecture
      ][:homepage]
      if remote_URL.is_a? Array
        remote_URL = remote_URL.first
      end
      e 'Trying to open the remote URL next: '+steelblue(remote_URL)
      do_open_this_url(remote_URL)
    # === :button_press
    when :butten_press # normal mouse button
      case event.button
      when 1 # left mouse button.
      when 2 # mitte
      when 3 # right click will be doing unselect-action.
        @tree_view.selection.unselect_all
      end 
    end
  }
end

#do_open_this_url(i) ⇒ Object

#

dop_open_this_url

#


184
185
186
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 184

def do_open_this_url(i)
  Open.in_browser(i)
end

#enable_custom_sorting_for_the_main_list_storeObject

#

enable_custom_sorting_for_the_main_list_store

#


334
335
336
337
338
339
340
341
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 334

def enable_custom_sorting_for_the_main_list_store
  # ======================================================================= #
  # Sort the file-size entry a bit differently.
  # ======================================================================= #
  @list_store.set_sort_func(2) { |_model, iter1, iter2|
    iter1[2].strip.to_f <=> iter2[2].strip.to_f
  }
end
#
#


318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 318

def handle_CSS_related_aspects
  use_gtk_paradise_project_css_file
  append_project_css_file
  add_custom_CSS_rules '
treeview.view header button {
color: royalblue;
font-size: 1.25em;
font-weight: bold;
}
  '
  do_apply_the_CSS_rules
end

#main_dataset?Boolean

#

main_dataset?

#

Returns:

  • (Boolean)


134
135
136
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 134

def main_dataset?
  @dataset_from_the_file_lecture_information
end

#resetObject

#

reset (reset tag)

#


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 78

def reset
  super() if respond_to?(:super)
  reset_the_internal_variables
  reset_the_base_module # This must come after reset_the_internal_variables().
  infer_the_namespace
  Studium.set_runmode :gui # Make it known that we use the gui-runmode in this case.
  # ======================================================================= #
  # === @configuration
  # ======================================================================= #
  @configuration = [true, __dir__, namespace?]
  # ======================================================================= #
  # === Set the title; this must come after we delegate to the
  #     @configuration object
  # ======================================================================= #
  set_title(
    return_the_title_from_the_config_file(true, @configuration)
  )
  # ======================================================================= #
  # === Set the title, width, height and the font in use.
  # ======================================================================= #
  title_width_height_font(title?, WIDTH, HEIGHT, USE_THIS_FONT)
  infer_the_size_automatically
  # ======================================================================= #
  # === @internal_hash[:smaller_font]
  # ======================================================================= #
  @internal_hash[:smaller_font] = SMALLER_FONT
  upon_delete_event_quit_the_application
  # ======================================================================= #
  # === @dataset_from_the_file_lecture_information
  # ======================================================================= #
  @dataset_from_the_file_lecture_information =
    ::Studium.return_sanitized_dataset_from_the_file_lecture_information
  # ======================================================================= #
  # === @use_this_curriculum
  #
  # Which curriculum to use. Currently this is hardcoded; in the
  # future this should be based on whatever dataset is loaded.
  # ======================================================================= #
  @use_this_curriculum = :bachelor_vektor
  handle_CSS_related_aspects if use_gtk3?
end

#return_widget_on_the_bottom_holding_statistical_information_about_this_curriculumObject

#

return_widget_on_the_bottom_holding_statistical_information_about_this_curriculum

#


170
171
172
173
174
175
176
177
178
179
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 170

def return_widget_on_the_bottom_holding_statistical_information_about_this_curriculum
  widget = create_vbox
  mini_hbox = create_hbox
  label_to_use = bold_label('n ECTS in total:')
  label_to_use.darkblue
  mini_hbox.minimal(label_to_use,           2)
  mini_hbox.minimal(@entry_n_ECTS_in_total, 2)
  widget.minimal(mini_hbox,                 2)
  return widget
end

#runObject

#

run (run tag)

#


499
500
501
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 499

def run
  run_super
end

#update_the_tree_view_with_this_curriculum(i) ⇒ Object

#

update_the_tree_view_with_this_curriculum (update tag)

#


451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
# File 'lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb', line 451

def update_the_tree_view_with_this_curriculum(i)
  i = i.first.to_s if i.is_a? Array
  i = i.to_sym
  @use_this_curriculum = i
  # ======================================================================= #
  # Obtain the dataset from the curriculum-file.
  # ======================================================================= #
  curriculum_dataset = ::Studium.read_dataset_from_a_curriculum_file(
    @use_this_curriculum, :remove_comments_and_title
  )
  e "Now using the curriculum `#{::Colours.steelblue(i)}`."
  main_dataset = main_dataset?
  @list_store.clear
  n_ECTS_in_total = 0
  curriculum_dataset.each {|this_entry|
    this_entry = this_entry.dup if this_entry.frozen?
    this_entry.squeeze!(' ')
    e 'Using the pointer for '+::Colours.steelblue(this_entry)+' next.'
    pointer        = main_dataset[this_entry]
    if pointer.nil?
      e 'Faulty entry for '+this_entry+'.'
      return
    end
    n_ects         = pointer[:ects].to_s.rjust(8)
    n_ECTS_in_total += n_ects.strip.to_f
    which_semester = pointer[:semester].to_s
    iter = @list_store.append
    splitted = this_entry.split(' ')
    lva_id   = splitted.first
    raw_name_of_the_lecture = splitted[1 .. -1].join(' ')
    already_solved = pointer[:already_solved]
    if already_solved
      already_solved_or_not = 'Yes'
    else
      already_solved_or_not = 'No'
    end
    iter.set_value(0, lva_id)
    iter.set_value(1, raw_name_of_the_lecture)
    iter.set_value(2, n_ects)
    iter.set_value(3, which_semester)
    iter.set_value(4, already_solved_or_not)
  }
  @entry_n_ECTS_in_total.set_text(n_ECTS_in_total.to_s)
end