Index: includes/admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/quicktabs/includes/Attic/admin.inc,v
retrieving revision 1.1.2.53
diff -u -r1.1.2.53 admin.inc
--- includes/admin.inc	10 Jan 2010 01:06:40 -0000	1.1.2.53
+++ includes/admin.inc	9 Apr 2010 17:45:23 -0000
@@ -103,17 +103,10 @@
     '#weight' => -10,
   );
 
-  $style_options = array();
-  $styles = module_invoke_all('quicktabs_tabstyles');
-  // The keys used for options must be valid html id-s.
-  foreach ($styles as $style) {
-    $style_options[$style] = $style;
-  }
-  ksort($style_options);
   $form['style'] = array(
     '#type' => 'select',
     '#title' => t('Style'),
-    '#options' => array('nostyle' => t('No style')) + array('default' => t('Default style')) + $style_options,
+    '#options' => quicktabs_style_options(),
     '#default_value' => isset($quicktabs['style']) ? $quicktabs['style'] : 'default',
     '#description' => t('Choose the quicktab style.'),
     '#weight' => -8,
Index: js/quicktabs.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/quicktabs/js/quicktabs.js,v
retrieving revision 1.3.2.20
diff -u -r1.3.2.20 quicktabs.js
--- js/quicktabs.js	8 Mar 2010 01:06:26 -0000	1.3.2.20
+++ js/quicktabs.js	9 Apr 2010 17:45:23 -0000
@@ -22,7 +22,7 @@
   $(el).find('ul.quicktabs_tabs li a').each(function(){
     this.myTabIndex = i++;
     this.qtid = qtid;
-    $(this).bind('click', quicktabsClick);
+    $(this).unbind('click').bind('click', quicktabsClick);
   });
 
   // Search for the active tab.
Index: quicktabs.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/quicktabs/quicktabs.module,v
retrieving revision 1.10.2.77
diff -u -r1.10.2.77 quicktabs.module
--- quicktabs.module	17 Mar 2010 00:12:31 -0000	1.10.2.77
+++ quicktabs.module	9 Apr 2010 17:45:22 -0000
@@ -28,6 +28,10 @@
       'arguments' => array('form' => NULL),
       'file' => 'includes/admin.inc',
     ),
+    'quicktabs_views_render' => array(
+      'arguents' => array('view' => NULL, 'tabs' => NULL, 'qtid' => NULL),
+      'file' => 'includes/quicktabs.views.inc',
+    ),
     'quicktabs_tabs' => array(
       'arguments' => array('quicktabs', 'active_tab' => 'none'),
     ),
@@ -441,6 +445,24 @@
 }
 
 /**
+ * Get a list of all available tab styles, suitable for use as an options array.
+ */
+function quicktabs_style_options($include_defaults = TRUE) {
+  $styles = module_invoke_all('quicktabs_tabstyles');
+  // The keys used for options must be valid html id-s.
+  foreach ($styles as $style) {
+    $style_options[$style] = $style;
+  }
+  ksort($style_options);
+
+  if ($include_defaults) {
+    $style_options = array('nostyle' => t('No style'), 'default' => t('Default style')) + $style_options;
+  }
+
+  return $style_options;
+}
+
+/**
  * Load the quicktabs data.
  */
 function quicktabs_load($qtid, $op = 'view') {
@@ -715,3 +737,13 @@
   }
   return $js_css;
 }
+
+/**
+ * Implementation of hook_views_api().
+ */
+function quicktabs_views_api() {
+  return array(
+    'api' => 2,
+    'path' => drupal_get_path('module', 'quicktabs') .'/includes',
+  );
+}
Index: includes/quicktabs_style_plugin.inc
===================================================================
RCS file: includes/quicktabs_style_plugin.inc
diff -N includes/quicktabs_style_plugin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/quicktabs_style_plugin.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,149 @@
+<?php
+// Id:$
+
+/**
+ * @file Add Quicktabs style plugins to Views.
+ */
+
+/**
+ * Style plugin to display Quicktabs.
+ */
+class quicktabs_style_plugin extends views_plugin_style {
+
+  // Allow some options for the style.
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['tab_style'] = array('default' => 'default');
+    $options['tab_title_field'] = array('default' => NULL);
+
+    return $options;
+  }
+
+  // Create the options form.
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['tab_style'] = array(
+      '#type' => 'select',
+      '#title' => t('Tab style'),
+      '#options' => quicktabs_style_options(),
+      '#default_value' => $this->options['tab_style'],
+      '#description' => t('The tab style that will be applied to this set of tabs. Note that this style may not show in the live preview.'),
+      '#weight' => -5,
+    );
+
+    if (isset($form['grouping'])) {
+      $options = $form['grouping']['#options'];
+      unset($options['']);
+      $form['tab_title_field'] = array(
+        '#type' => 'select',
+        '#title' => t('Title field'),
+        '#options' => $options,
+        '#required' => TRUE,
+        '#default_value' => $this->options['tab_title_field'],
+        '#description' => t('Select the field that will be used as the tab title.'),
+        '#weight' => -3,
+      );
+    }
+  }
+
+  // Ensure we have all the settings necessary to render into tabs.
+  function validate() {
+    $errors = parent::validate();
+
+    // Ensure that we're using the field row style.
+    if (!$this->row_plugin->uses_fields()) {
+      $errors[] = t('Display "@display" uses the "@style" row style, but the Quicktabs display style requires use of the "Fields" row style.', array('@display' => $this->display->display_title, '@style' => $this->row_plugin->definition['title']));
+    }
+
+    // Ensure that a valid tab title field is selected.
+    $fields = $this->display->handler->get_handlers('field');
+    if (empty($this->options['tab_title_field']) || !isset($fields[$this->options['tab_title_field']])) {
+      $errors[] = t('The Quicktabs display style requires that a field be configured to be used as the tab title.');
+    }
+
+    return $errors;
+  }
+
+  // Override the render functionality.
+  function render() {
+    if (empty($this->row_plugin)) {
+      vpr('views_plugin_style_default: Missing row plugin');
+      return;
+    }
+
+    $view = $this->view;
+    $qtid = 'view__' . $view->name .'__'. $view->current_display;
+
+    // Group the rows according to the grouping field, if specified.
+    $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
+    $tabs = array();
+
+    foreach ($sets as $title => $records) {
+      if ($this->uses_row_plugin()) {
+        $rows = array();
+        foreach ($records as $row_index => $row) {
+          $this->view->row_index = $row_index;
+          $rows[] = $this->row_plugin->render($row);
+        }
+      }
+      else {
+        $rows = $records;
+      }
+
+      // If grouped, we'll be using the group title for each tab.
+      if ($this->options['grouping']) {
+        // Remove labels from titles.
+        $grouping_field = $this->options['grouping'];
+        if ($this->view->field[$grouping_field]->options['label']) {
+          $title = str_replace($this->view->field[$grouping_field]->options['label'] . ': ', '', $title);
+        }
+
+        $tabs[] = array(
+          'title' => $title,
+          'content' => $rows,
+        );
+      }
+
+      // If not grouped, there's just one set of rows that we loop through.
+      else {
+        foreach ($rows as $index => $row) {
+          $title = $this->get_field($index, $this->options['tab_title_field']);
+          $tabs[] = array(
+            'title' => $title,
+            'content' => $row,
+          );
+        }
+      }
+    }
+
+    $output = theme('quicktabs_views_render', $view, $tabs, $qtid);
+
+    // If doing a live preview, add the JavaScript directly to the output.
+    if (isset($view->live_preview) && $view->live_preview) {
+      $js = drupal_add_js();
+      $qtsettings = array();
+      foreach ($js['setting'] as $settings) {
+        if (isset($settings['quicktabs']['qt_'. $qtid])) {
+          $qtsettings = $settings['quicktabs']['qt_'. $qtid];
+          break;
+        }
+      }
+
+      $output .= "<script type=\"text/javascript\">\n";
+      $output .= "Drupal.settings.quicktabs = Drupal.settings.quicktabs || {};\n";
+      $output .= "jQuery.extend(Drupal.settings.quicktabs, ". drupal_to_js(array('qt_'. $qtid => $qtsettings)) .");\n";
+      $output .= "</script>\n";
+    }
+
+    unset($view->row_index);
+    return $output;
+  }
+
+  // Because we don't provide templates, but Views may complain when visiting
+  // the theme information if it can't find any. Specify the name of our theme
+  // function to keep it from causing any errors.
+  function theme_functions() {
+    return array('quicktabs_view_render');
+  }
+}
Index: includes/quicktabs.views.inc
===================================================================
RCS file: includes/quicktabs.views.inc
diff -N includes/quicktabs.views.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/quicktabs.views.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,56 @@
+<?php
+// Id:$
+
+/**
+ * @file Add Views module hooks to Quicktabs.
+ */
+ 
+/**
+ * Implementation of hook_views_plugins().
+ */
+function quicktabs_views_plugins() {
+  $path = drupal_get_path('module', 'quicktabs');
+  
+  return array(
+    'style' => array(
+      'quicktabs' => array(
+        'title' => t('Quicktabs'),
+        'help' => t('Display view in Quicktabs.'),
+        'handler' => 'quicktabs_style_plugin',
+        'path' => "$path/includes",
+        'theme' => 'quicktabs_view',
+        'uses row plugin' => TRUE,
+        'uses options' => TRUE,
+        'type' => 'normal',
+      ),
+    ),
+  );
+}
+
+function theme_quicktabs_views_render($view, $tabs, $qtid) {
+  foreach ($tabs as $index => $tab) {
+    if (is_array($tab['content'])) {
+      $text = '';
+      foreach ($tabs[$index]['content'] as $content) {
+        $text .= '<div class="quicktabs-views-group">' . $content . '</div>';
+      }
+      $tabs[$index]['text'] = $text;
+    }
+    else {
+      $tabs[$index]['text'] = $tabs[$index]['content'];
+    }
+    $tabs[$index]['type'] = 'freetext';
+    unset($tabs[$index]['content']);
+  }
+
+  $quicktabs = array(
+    'qtid' => $qtid,
+    'ajax' => '0', // TODO: Support AJAX, set this to $view->use_ajax.
+    'hide_empty_tabs' => '0',
+    'default_tab' => '0',
+    'style' => $view->style_options['tab_style'],
+    'tabs' => $tabs,
+  );
+
+  return theme('quicktabs', $quicktabs);
+}
