public DetailsFrame(CourseModel model, final Settings settings) {
		super("Details", model);
		JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		this.setContentPane(split);
		model.addListener(this);

		Dimension dim = new Dimension(400, 200);
		this.setMinimumSize(dim);
		this.setSize(dim);

		tableModel = new OfferingTableModel(model);
		offeringTable = new JTable(tableModel);
		offeringTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		offeringTable.setDefaultRenderer(Status.class, new StatusCellRenderer(
				settings));
		offeringTable
				.getColumnModel()
				.getColumn(0)
				.setCellEditor(
						new DefaultCellEditor(new StatusComboBox(Status
								.getAll(), settings)));
		offeringTable.getColumnModel().getColumn(1)
				.setCellRenderer(new DefaultTableCellRenderer() {
					@Override
					public Component getTableCellRendererComponent(
							JTable table, Object value, boolean isSelected,
							boolean hasFocus, int row, int column) {
						JLabel res = (JLabel) super
								.getTableCellRendererComponent(table, value,
										isSelected, hasFocus, row, column);
						res.setHorizontalAlignment(SwingConstants.TRAILING);
						return res;
					}
				});
		offeringTable.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() != MouseEvent.BUTTON3)
					return;
				int col = offeringTable.columnAtPoint(e.getPoint());
				if (col != 2)
					return;
				int row = offeringTable.rowAtPoint(e.getPoint());
				final OffRec off = tableModel.getOfferingAt(row);
				// Only show for EdX
				if (off.getCourse().getSource() != Source.EDX)
					return;
				JPopupMenu offeringPopupMenu = new JPopupMenu();
				AbstractAction askToLoadEdXDuration = new AbstractAction(
						"Load duration") {
					@Override
					public void actionPerformed(ActionEvent e) {
						EdxModelAdapter edx = new EdxModelAdapter();
						try {
							if (edx.loadClassDuration(
									off,
									new Boolean(
											settings.getString(Settings.IGNORE_SSL_CERT)))) {
								tableModel.saveModelAndInform();
							} else {
								JOptionPane
										.showMessageDialog(null,
												"Could not figure out the duration from EdX webpage");
							}
						} catch (IOException ex) {
							// wait.setVisible(false);
							JOptionPane.showMessageDialog(null,
									"Failed to load EdX data:\n" + ex);
							return;
						}
					}
				};
				offeringPopupMenu.add(askToLoadEdXDuration);
				offeringPopupMenu.show(offeringTable, e.getX(), e.getY());
			}
		});

		JScrollPane tablePane = new JScrollPane(offeringTable);
		Dimension minTableSize = new Dimension(50, 70);
		tablePane.setMinimumSize(minTableSize);
		split.setLeftComponent(tablePane);
		htmlPane = new JTextPane();
		split.setRightComponent(new JScrollPane(htmlPane));
		htmlPane.setContentType("text/html");
		htmlPane.setEditable(false);
		htmlPane.addHyperlinkListener(new HyperlinkListener() {
			@Override
			public void hyperlinkUpdate(HyperlinkEvent e) {
				if (EventType.ACTIVATED.equals(e.getEventType())
						&& e.getURL() != null) {
					Desktop desktop = java.awt.Desktop.getDesktop();
					try {
						desktop.browse(e.getURL().toURI());
					} catch (Exception e1) {
						JOptionPane.showMessageDialog(null,
								"Cannot open browser for\n" + e.getURL() + "\n"
										+ e1.getMessage());
					}
				}
			}
		});

		offeringTable.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {
					@Override
					public void valueChanged(ListSelectionEvent e) {
						updateHtml();
					}
				});
	}