Class: Ruber::ChoosePluginsWidget

Inherits:
Qt::Widget
  • Object
show all
Defined in:
lib/ruber/main_window/choose_plugins_dlg.rb

Overview

Widget which implements most of the functionality of the ChoosePluginsDlg class.

It contains a list of plugins in the current search path, where the user can choose the plugins to load (using checkboxes), and a list of directories where the user can choose where to look for plugins.

In the plugin list, chosen plugins are shown with a selected mark, while plugins which will be loaded to satisfy the dependencies of chosen plugins will be shown with a partial mark.

Whenever the user changes the chosen plugins, the dependencies are re-computed. If there’s a problem, the user is warned with a message box.

Instance Method Summary (collapse)

Signal Summary

Constructor Details

- (ChoosePluginsWidget) initialize(parent = nil)

Creates a new ChoosePluginsWidget.

The list of directories where to look for plugins is read from the configuration file. The chosen plugins are read from the configuration file, but excluding all those which aren’t currently loaded (the reason to do so is that a chosen plugin might have failed to load and thus it should not appear in the chosen list). Also, any plugin which is included in the chosen list but whose PDF can’t be found is excluded.

Dependencies are then computed, and dependencies of the chosen plugins are marked as such. If a dependency problem occurs, the user is warned and all plugins are deselected.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 123

def initialize parent = nil
  super
  @ui = Ui::ChoosePluginsWidget.new
  @ui.setupUi self
  
  dirs = Ruber[:app].plugin_dirs
  
  @chosen_plugins = Ruber[:config][:general, :plugins].map(&:to_sym)
  loaded = Ruber[:components].plugins.map(&:plugin_name)
  @chosen_plugins.delete_if{|i| !loaded.include? i}
  
  read_plugins dirs
  res = find_deps(:sorry) do |e| 
    "There were problems making dependencies. #{create_failure_message e}\nAll plugins will be deselected"
  end
  if res
    @chosen_plugins.clear
    @needed_plugins = []
  end
  m = Qt::StandardItemModel.new @ui.plugins
  @ui.plugins.model = m
  
  connect m, SIGNAL('itemChanged(QStandardItem*)'), self, SLOT('plugin_toggled(QStandardItem*)')
  
#       def m.flags idx
#         Qt::ItemIsSelectable|Qt::ItemIsEnabled| Qt::ItemIsUserCheckable
#       end
  
  @url = KDE::UrlRequester.new self
  @ui.directories.custom_editor = @url.custom_editor
  @url.mode = KDE::File::Directory | KDE::File::LocalOnly
  connect @ui.directories, SIGNAL(:changed), self, SLOT(:slot_directories_changed)      
  @ui.directories.items = dirs
  
  fill_plugin_list
end

Instance Method Details

- (Object) apply_defaults

Sets both the chosen plugins and the plugin directories to their default values (see Appplication::DEFAULT_PLUGIN_PATHS and Application::DEFAULT_PLUGINS). If a dependency problem occurs, the user is warned and all plugins are deselected



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 187

def apply_defaults
  dirs = Ruber[:config].default :general, :plugin_dirs
  @chosen_plugins = Ruber[:config].default( :general, :plugins).split(',').map{|i| i.to_sym}
  read_plugins dirs
  res = find_deps(:sorry) do |e| 
    "There were problems making dependencies. #{create_failure_message e}\nAll plugins will be deselected"
  end
  if res
    @chosen_plugins.clear
    @needed_plugins = []
  end
  @ui.directories.clear
  @ui.directories.items = dirs
  
  fill_plugin_list
end

Slot Signature:

apply_defaults()

- (Object) create_failure_message(e) (private)

Creates an appropriate failure message for the exception e, which should be an instance of ComponentManager::DependencyError. It is meant to generate consistent error messages for all the places in the widget where a dependency error can happen.



339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 339

def create_failure_message e
  case e
  when ComponentManager::UnresolvedDep
    deps = e.missing.map do |p1, p2|
      "#{p1}, needed by #{p2.join ', '}"
    end
    "Some dependencies couldn't be satisifed:\n#{deps.join "\n"}"
  when ComponentManager::CircularDep
    deps = e.missing.map do |p1, p2|
      "#{p1} and #{p2}"
    end
    "There were circular dependencies between the following plugins:\n#{deps.join "\n"}"
  end
end

- (Boolean) deps_satisfied?

Returns false if there’s a dependency problem among the chosen plugins and true otherwise.

Returns:

  • (Boolean)


208
209
210
211
212
213
214
215
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 208

def deps_satisfied?
  begin 
    find_deps
    true
  rescue ComponentManager::UnresolvedDep, ComponentManager::CircularDep
    false
  end
end

- (Object) fill_plugin_list (private)

Fills the list of plugins with the names, descriptions and paths of all plugins found and marks each one according to whether it is among the chosen plugins, the needed plugins or neither.

It also resizes the columns of the plugin list widget so that they match the size of the contents.



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 270

def fill_plugin_list
  m = @ui.plugins.model
  m.clear
  m.horizontal_header_labels = %w[Name Description Directory]
  @plugins_files.each do |k, v|
    name = Qt::StandardItem.new v.about.human_name
    name.data = Qt::Variant.new(k.to_s)
    desc = Qt::StandardItem.new v.about.description
    dir = Qt::StandardItem.new v.directory
    row = [name, desc, dir]
    row.each{|i| i.flags = Qt::ItemIsSelectable|Qt::ItemIsEnabled}
    name.flags |= Qt::ItemIsUserCheckable
    m.append_row row
  end
  update_plugin_status
  3.times{|i| @ui.plugins.resize_column_to_contents i}
end

- (Object) find_deps(msg_type = :sorry) (private)

Finds the dependencies of the chosen plugins and stores them in the @needed_plugins instance variable. If a dependency error occurs, if a block was passed, a message box of type type is displayed. The text of the message box is obtained by calling the block with the exception as argument. If an error occurs and no block is passed, the exception is passed on.

This method returns nil if no error occurs and the value returned by the message box otherwise.



251
252
253
254
255
256
257
258
259
260
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 251

def find_deps msg_type = :sorry
  chosen_data = @chosen_plugins.map{|i| @plugin_data[i]}
  begin @needed_plugins = ComponentManager.fill_dependencies chosen_data, @plugin_data.values
  rescue ComponentManager::UnresolvedDep, ComponentManager::CircularDep => e
    if block_given? then KDE::MessageBox.send msg_type, nil, yield(e)
    else raise
    end
  end
  nil
end

- (Object) plugin_toggled(it) (private)

Updates the plugin status to reflect the changes made to the plugin corresponding to the item it.



309
310
311
312
313
314
315
316
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 309

def plugin_toggled it
  name = it.data.to_string
  if it.check_state == Qt::Checked then @chosen_plugins << name.to_sym
  else @chosen_plugins.delete name.to_sym
  end
  find_deps{|e| create_failure_message( e) + "\nPlease, be sure to correct the problem before pressing the OK or Apply button" }
  update_plugin_status
end

Slot Signature:

plugin_toggled(QStandardItem*)

- (Object) plugins

Returns a hash containing both the chosen plugins and their dependencies. The keys are the plugin names, while the values are the directories of the plugins.



221
222
223
224
225
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 221

def plugins
  @ui.plugins.model.enum_for(:each_row).map do |name, _, dir|
    [name.data.to_string.to_sym, dir.text] if name.checked?
  end.compact.to_h
end

- (Object) read_plugins(dirs) (private)

Finds all the plugins in subdirectories of directories in the dir array, reads their PDFs and stores the data in the plugins_files</tt> and <tt>plugin_data instance variables. Also removes from the @chosen instance variable the plugins whose PDF wasn’t found.



235
236
237
238
239
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 235

def read_plugins dirs
  @plugins_files = ComponentManager.find_plugins dirs, true
  @plugin_data = @plugins_files.map{|_, v| [v.name, v]}.to_h
  @chosen_plugins.delete_if{|i| !@plugin_data[i]}
end

- (Object) sizeHint

:nodoc:



161
162
163
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 161

def sizeHint #:nodoc:
  Qt::Size.new 600, 550
end

- (nil) slot_directories_changed (private)

Updates the plugin widgets and emits the signal

If the dependencies aren’t respected, the user is warned with a message box.

Returns:

  • (nil)


324
325
326
327
328
329
330
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 324

def slot_directories_changed
  new_dirs = @ui.directories.items
  find_deps{|e| create_failure_message( e) + "\nPlease, be sure to correct the problem before pressing the OK or Apply button" }
  fill_plugin_list
  emit directories_changed
  nil
end

Slot Signature:

slot_directories_changed()

- (Object) update_plugin_status (private)

Changes the contents of the chosen_plugins</tt> and <tt>needed_plugins instance variable to reflect the checked status of the plugins in the plugin list widget. Emits the plugins_changed signal.



293
294
295
296
297
298
299
300
301
302
303
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 293

def update_plugin_status
  @ui.plugins.model.each_row do |name, desc, dir|
    plug_name = name.data.to_string.to_sym
    state = if @chosen_plugins.include? plug_name then Qt::Checked
    elsif @needed_plugins.include? plug_name then Qt::PartiallyChecked
    else Qt::Unchecked
    end
    name.check_state = state
  end
  emit plugins_changed
end

- (Object) write_settings

Writes the settings to the configuration file. The directories listed in the directory widget are stored in the general/plugin_dirs entry, while the chosen plugins are stored in the general/plugins entry. Plugins which haven’t been chosen but are dependencies of the chosen ones aren’t stored.



171
172
173
174
175
176
177
178
179
180
# File 'lib/ruber/main_window/choose_plugins_dlg.rb', line 171

def write_settings
  dirs = @ui.directories.items
  Ruber[:app].plugin_dirs = dirs
  plugins = []
  @ui.plugins.model.each_row do |r|
    plugins << r[0].data.to_string if  r[0].fully_checked?
  end
  Ruber[:config][:general, :plugins] = plugins
  Ruber[:config].write
end

Slot Signature:

write_settings()

Signal Details

- directories_changed

- plugins_changed