Logo Search packages:      
Sourcecode: packagesearch version File versions

packagesearchimpl.cpp

//
// C++ Implementation: packagesearchimpl
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include "packagesearchimpl.h"

#include <iostream>
#include <algorithm>

#include <qaction.h>
#include <qapplication.h>
#include <qcombobox.h>
#include <qcursor.h>
#include <qdir.h>
#include <qframe.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qlistbox.h>
#include <qlistview.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qpopupmenu.h>
#include <qstatusbar.h>
#include <qtabwidget.h>
#include <qtextbrowser.h>
#include <qclipboard.h>
#include <qheader.h>
#include <qsplitter.h>

// #include <apt-pkg/error.h>
// #include <apt-pkg/pkgcachegen.h>
// // #include <apt-pkg/progress.h>
// #include <apt-pkg/sourcelist.h>
// #include <apt-pkg/pkgrecords.h>
// #include <apt-pkg/tagfile.h>
// #include <apt-pkg/algorithms.h>
// #include "cacheaccess.h"

#include "extalgorithm.h"
#include "helpers.h"
#include "runcommandforoutput.h"


// namespace NPlugin 
#include "plugin.h"
#include "searchplugin.h"
#include "informationplugin.h"
#include "shortinformationplugin.h"
#include "plugincontainer.h"
#include "pluginmanager.h"
#include "plugincompare.h"
#include "packagenotfoundexception.h"
#include "packagenameplugin.h"

#include "xmldata.h"
#include "singlehandlemaker.h"
#include "columncontroldlg.h"
#include "packagelistviewitem.h"

using namespace std;

PackageSearchImpl::PackageSearchImpl( QWidget* parent, const char* name, WFlags fl )
: PackageSearch(parent, name, fl), _DETAILS_INFORMATION_PRIORITY(2)
{
      _pPackageNamePlugin = 0;
      _settingsFilename = QDir::homeDirPath()+"/.packagesearch";
      _pHandleMaker = SingleHandleMaker::instance();
      _pInformationDetailsPage = _pInformationContainer->page(0);

      // update the shown short information order whenever oder changes
      connect(_pPackageView->header(), SIGNAL(indexChange(int, int, int)), this, SLOT(refreshShownAndHidden()));
      
      vector<string> pluginDirectories;
      pluginDirectories.push_back("plugins/");
      pluginDirectories.push_back("/usr/lib/packagesearch/");
      _pPluginManager = new NPlugin::PluginManager(pluginDirectories, this, this);
      _pPluginManager->addPluginUser(this);
      loadSettings();   // must be called after setting _pPluginManager but before calling loadPlugins
}

PackageSearchImpl::~PackageSearchImpl()
{
      delete _pPackageNamePlugin;
}

00094 void PackageSearchImpl::initialize()
{
      // create the hard coded plugin
      _pPackageNamePlugin = new NPlugin::PackageNamePlugin();
      this->addPlugin(_pPackageNamePlugin);

      _pPluginManager->loadPlugins();
      if (_plugins.empty())   // if no plugins were loaded
      {
            reportWarning("No Plugins Loaded","This program needs plugins to do anything usefull at all.<br>"
                  "Please install or activate some plugins.");
      }
      _pInformationContainer->setCurrentPage(0);
      const set<string>& packages_ = packages();
      for (set<string>::const_iterator it = packages_.begin(); it != packages_.end(); ++it)
            _pPackageSelection->insertItem(toQString(*it));
      _pPackageSelection->setMinimumWidth(100);
      _pPackageSelection->setCurrentText("");
}

/////////////////////////////////////////////////////
// IProvider Interface
/////////////////////////////////////////////////////

00118 void PackageSearchImpl::setEnabled(bool enabled)
{
      QMainWindow::setEnabled(enabled);
}

00123 QPopupMenu* PackageSearchImpl::systemMenu() const
{
      return _pSystemMenu;
}

00128 void PackageSearchImpl::reportError(const QString& title, const QString& message)
{
      QMessageBox::critical(this, title, message, "OK");
}

00133 void PackageSearchImpl::reportWarning(const QString& title, const QString& message)
{
      QMessageBox::warning(this, title, message, "OK");
}

/** Predicate to compare pointer to plugins by priority. */
template <typename PluginType> 
00140 class LesserPriority : binary_function<PluginType*, PluginType* ,bool>
{
public:
      bool operator()(PluginType* p1, PluginType* p2)
      {
            return (*p1) < (*p2);
      }
};

00149 Tagcoll::HandleMaker<string>& PackageSearchImpl::handleMaker() const
{
      return *_pHandleMaker;
}

00154 void PackageSearchImpl::reportBusy(NPlugin::Plugin* pPlugin, const QString& message)
{
      qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
      statusBar()->message(message);
}

00160 void PackageSearchImpl::reportReady(NPlugin::Plugin* pPlugin)
{
      qApp->restoreOverrideCursor();
      statusBar()->message(tr("Ready"));
}


00167 NUtil::IProgressObserver* PackageSearchImpl::progressObserver()
{
      return _pPluginManager->progressObserver();
}


00173 const set<string>& PackageSearchImpl::packages()
{
      static bool initialized = false;
      if (!initialized)
      {     
            // I used to use the real apt code here, but I gained only around 400ms this is not worth the
            // effort...
            QTime t;
            t.start();
            initialized = true;
            NApplication::RunCommandForOutput ro("");
            ro.run("apt-cache pkgnames --no-all-names");
            QStringList packages = ro.getOutput();
            for(QStringList::iterator it = packages.begin(); it != packages.end(); ++it)
                  _packages.insert(toString(*it));
            
            // code directly taken from apt-cache ShowPkgNames and main
/*          CacheAccess ca;
            pkgCache::PkgIterator I = ca.pCache()->PkgBegin();
            // Show all pkgs
            for (;I.end() != true; I++)
            {
                  if (I->VersionList == 0)      // if it is not a real package
                        continue;
                  _packages.insert(I.Name());
            }
            qDebug("creating package list: %d ms", t.elapsed());*/
      }
      return _packages;
}


/////////////////////////////////////////////////////
// IPluginUser Interface
/////////////////////////////////////////////////////

00209 void PackageSearchImpl::addPlugin(NPlugin::Plugin* pPlugin)
{
      using namespace NPlugin;
      _plugins.push_back(pPlugin);

      SearchPlugin* pSearchPlugin = dynamic_cast<SearchPlugin*>(pPlugin);
      if (pSearchPlugin != 0)
      {
            _searchPlugins.push_back(pSearchPlugin);
            sort(_searchPlugins.begin(), _searchPlugins.end(), LesserPriority<SearchPlugin>());
            updateSearchPluginGui();
            connect(pSearchPlugin, SIGNAL(searchChanged(NPlugin::SearchPlugin*)), 
                  SLOT(onSearchChanged(NPlugin::SearchPlugin*)));
            /// @todo connect selectionChanged signal
      }
      InformationPlugin* pInformationPlugin = dynamic_cast<InformationPlugin*>(pPlugin);
      if (pInformationPlugin != 0)
      {
            _informationPlugins.push_back(pInformationPlugin);
            sort(_informationPlugins.begin(), _informationPlugins.end(), 
                  LesserPriority<InformationPlugin>());
            updateInformationPluginGui();
      }
      ShortInformationPlugin* pShortInformationPlugin = dynamic_cast<ShortInformationPlugin*>(pPlugin);
      if (pShortInformationPlugin != 0)
      {
            _shortInformationPlugins.push_back(pShortInformationPlugin);
            sort(_shortInformationPlugins.begin(), _shortInformationPlugins.end(),
                  LesserPriority<ShortInformationPlugin>());
            updateShortInformationPluginGui();
      }
}


00243 void PackageSearchImpl::addPlugin(NPlugin::PluginContainer* pPlugin)
{
      assert(pPlugin!= 0);
      
      // add the actions offered by this plugin container to the menu
      vector< pair<QString, QAction*> > actions = pPlugin->actions();
      NExtStd::for_each(actions.begin(), actions.end(), &PackageSearchImpl::addMenuEntry, this);
      
      // add all plugins offered by this container
      vector<string> offeredPlugins = pPlugin->offeredPlugins();
      for ( vector<string>::iterator it = offeredPlugins.begin(); it != offeredPlugins.end(); ++it)
            addPlugin(pPlugin->requestPlugin(*it));
}

00257 void PackageSearchImpl::removePlugin(NPlugin::Plugin* pPlugin)
{
      using namespace NPlugin;
      SearchPlugin* pSPlugin = dynamic_cast<SearchPlugin*>(pPlugin);
      if (pSPlugin)
      {
            SearchPluginContainer::iterator it = 
                  std::find(_searchPlugins.begin(), _searchPlugins.end(), pSPlugin);
            if (it != _searchPlugins.end())
            {
                  _searchPlugins.erase(it);
                  updateSearchPluginGui();
            }
      }
      InformationPlugin* pIPlugin = dynamic_cast<InformationPlugin*>(pPlugin);
      if (pIPlugin)
      {
            InformationPluginContainer::iterator it = 
                  std::find(_informationPlugins.begin(), _informationPlugins.end(), pIPlugin);
            if (it != _informationPlugins.end())
            {
                  _informationPlugins.erase(it);
                  updateInformationPluginGui();
            }
      }
      ShortInformationPlugin* pSIPlugin = dynamic_cast<ShortInformationPlugin*>(pPlugin);
      if (pSIPlugin)
      {
            ShortInformationPluginContainer::iterator it = 
                  std::find(_shortInformationPlugins.begin(), _shortInformationPlugins.end(), pSIPlugin);
            if (it != _shortInformationPlugins.end())
            {
                  _shortInformationPlugins.erase(it);
            }
            map<ShortInformationPlugin*, int>::iterator jt = _shortInformationColumn.find(pSIPlugin);
            // if the plugin was shown
            if (jt != _shortInformationColumn.end())
            {
                  _shortInformationColumn.erase(jt);
                  updateShortInformationPluginGui();
            }
      }
      PluginContainer::iterator it = 
            std::find(_plugins.begin(), _plugins.end(), pPlugin);
      if (it != _plugins.end())
      {
            _plugins.erase(it);
      }
}


/////////////////////////////////////////////////////
// Helper Methods
/////////////////////////////////////////////////////

00312 void PackageSearchImpl::updateSearchPluginGui()
{
      // remove all pages
      while ( _pInputWidgetsContainer->count() > 0)
      {
            _pInputWidgetsContainer->removePage(_pInputWidgetsContainer->page(0) );
      }
      // delete the old layout for the frame
      delete _pShortSearchFrameLayout;
      // replace by a new one
      _pShortSearchFrameLayout = new QVBoxLayout( _pShortSearchFrame, 5, 10, "_pShortSearchFrameLayout"); 

      
      //_pShortSearchFrame->layout()
      NExtStd::for_each(_searchPlugins.begin(), _searchPlugins.end(), 
            &PackageSearchImpl::addSearchPluginToGui, this);
      /// @todo this seemed to be neccessary because the tab widget behaved really odd
      _pInputWidgetsContainer->setCurrentPage(1);
      if (_pInputWidgetsContainer->count()>0)
            _pInputWidgetsContainer->setCurrentPage(0);
}

00334 void PackageSearchImpl::addSearchPluginToGui(NPlugin::SearchPlugin* pPlugin)
{
      assert(pPlugin);
      // add the input widget
      if (pPlugin->inputWidget() != 0)
      {
            _pInputWidgetsContainer->addTab(pPlugin->inputWidget(), pPlugin->inputWidgetTitle());
      }
      // add the short input widget
      if (pPlugin->shortInputAndFeedbackWidget()!=0)
      {
            QWidget* pWidget = pPlugin->shortInputAndFeedbackWidget();
            // store if the widget was shown to as reparenting destroys this state
            bool shown = pWidget->isShown();
            // reparenting was the only way which seemed to work to get the widgets where I wanted them :-(
            pWidget->reparent(
                  _pShortSearchFrame, 0, QPoint()
            );
            _pShortSearchFrame->layout()->add(pWidget);
            pWidget->setShown(shown);
      }
}

00357 void PackageSearchImpl::updateInformationPluginGui()
{
      QString tmpCurrentPackage = _currentPackage;
      _currentPackage =  "";
      // clear the information plugin GUI except the first page
      while ( _pInformationContainer->count() > 0)
      {
            _pInformationContainer->removePage(_pInformationContainer->page(0) );
      }
      // add a dummy tab, so that the widgets are not allways repainted
      bool detailPageAdded = false;
      for (InformationPluginContainer::iterator it = _informationPlugins.begin();
            it != _informationPlugins.end(); ++it)
      {
            if ( !detailPageAdded && 
                  ((*it)->informationPriority() >= _DETAILS_INFORMATION_PRIORITY) )
            {
                  _pInformationContainer->insertTab(_pDetailsView, tr("Details"));
                  detailPageAdded = true;
            }
            addInformationPluginToGui(*it);
      }
      if (!detailPageAdded)
            _pInformationContainer->insertTab(_pDetailsView, tr("Details"));
      _pInformationContainer->showPage(_pInformationContainer->page(0));
      setSelectedPackage(tmpCurrentPackage);
/*    {
            QWidget* pParent = dynamic_cast<QWidget*>(_pInformationContainer->parent());
            delete _pInformationContainer;
            _pInformationContainer = new QTabWidget(pParent, "InformationContainer");
            _pDetailsView = new QTextBrowser( _pInformationContainer, "_pDetailsView" );
            bool detailPageAdded = false;
            for (InformationPluginContainer::iterator it = _informationPlugins.begin();
                  it != _informationPlugins.end(); ++it)
            {
                  if ( !detailPageAdded && 
                        ((*it)->informationPriority() >= _DETAILS_INFORMATION_PRIORITY) )
                  {
                        _pInformationContainer->insertTab(_pDetailsView, tr("Details"));
                        detailPageAdded = true;
                  }
                  addInformationPluginToGui(*it);
            }
            _pInformationLayout->add(_pInformationContainer);
      }*/
}


00405 void PackageSearchImpl::addInformationPluginToGui(NPlugin::InformationPlugin* pPlugin)
{
      assert(pPlugin);
      if (pPlugin->informationWidget() != 0)    // if there is a special information widget
      {
            // insert the widget
            _pInformationContainer->insertTab(
                  pPlugin->informationWidget(), 
                  pPlugin->informationWidgetTitle()
            );
      }
}

// unnamed namespace to hide function object
namespace 
{
/** @brief This function object can be used to compare the caption of ShortInformationPlugin 
  * with QString objects.
  * 
  * Returns true if they are equal.
  */
class ShortInformationCaptionEquals
{
      const QString _caption;
public:
      ShortInformationCaptionEquals(const QString caption) :
            _caption(caption)
      {}
      bool operator() (const NPlugin::ShortInformationPlugin* pPlugin)
      {
            return pPlugin->shortInformationCaption() == _caption;
      }
};

00439 void PackageSearchImpl::updateShortInformationPluginGui()
{
      // remove all except the first column
      while ( _pPackageView->columns() > 0)
            _pPackageView->removeColumn(0);
/*    NExtStd::for_each(_shortInformationPlugins.begin(), _shortInformationPlugins.end(),
            &PackageSearchImpl::addShortInformationPluginToGui, this);*/
      const int CHAR_WIDTH = 7;
      const int MARGIN = 10;
      // sorted list of ShortInformationPlugins
      ShortInformationPluginContainer plugins = _shortInformationPlugins;
      // holds the plugins shown in order of priority
      ShortInformationPluginContainer shownPlugins;
      // add the shown plugins to be displayed and removed them from "plugins"
      for (QStringList::const_iterator it = _shownShortInformation.begin(); 
                  it != _shownShortInformation.end(); ++it)
      {
            ShortInformationPluginContainer::iterator jt = find_if(plugins.begin(), plugins.end(), ShortInformationCaptionEquals(*it));
            if (jt != plugins.end())
            {
                  NPlugin::ShortInformationPlugin* pPlugin = *jt;
                  int columnWidth = (pPlugin->preferredColumnWidth() == -1) ? -1 : (pPlugin->preferredColumnWidth() * CHAR_WIDTH + MARGIN);
                  int column = _pPackageView->addColumn(pPlugin->shortInformationCaption(), columnWidth);
                  _shortInformationColumn[pPlugin] = column;
                  _pPackageView->setColumnWidthMode(column, QListView::Manual);
                  plugins.erase(jt);
                  shownPlugins.push_back(*jt);
                  qDebug("Adding known plugin "+pPlugin->shortInformationCaption()+" as %d", _shortInformationColumn[pPlugin]);
            }
      }
      // remove the hidden plugins from "plugins"
      for (QStringList::const_iterator it = _hiddenShortInformation.begin(); 
                  it != _hiddenShortInformation.end(); ++it)
      {
            ShortInformationPluginContainer::iterator jt = find_if(plugins.begin(), plugins.end(), ShortInformationCaptionEquals(*it));
            if (jt != plugins.end())
                  plugins.erase(jt);
      }
      // handle new plugins (neither shown nor hidden) adding them before the first
      // plugin which has a priority greater than the one of the new one
      for ( ShortInformationPluginContainer::iterator it = plugins.begin();
            it != plugins.end(); ++it )
      {
            NPlugin::ShortInformationPlugin* pPlugin = *it;
            qDebug("Adding new plugin "+pPlugin->shortInformationCaption()+" as %d", _shortInformationColumn[pPlugin]);
            int columnWidth = (pPlugin->preferredColumnWidth() == -1) ? -1 
                        : (pPlugin->preferredColumnWidth() * CHAR_WIDTH + MARGIN);
            int column = _pPackageView->addColumn(pPlugin->shortInformationCaption(), columnWidth);
            _shortInformationColumn[pPlugin] = column;
            _shortInformationColumn[pPlugin] = column;
            _pPackageView->setColumnWidthMode(column, QListView::Manual);

            // not working because pointer spoil the show (the binder can't cope with this :-(
//          LesserPriority<NPlugin::ShortInformationPlugin> cmp;
//          ShortInformationPluginContainer::const_iterator jt = find_if(plugins.begin(), plugins.end(), bind1st<NPlugin::ShortInformationPlugin*>(cmp, pPlugin));
            ShortInformationPluginContainer::const_iterator jt;
            // find the first plugin with a higher priority value (i.e. a lower piority)
            for (jt = shownPlugins.begin(); jt != shownPlugins.end(); ++jt)
            {
                  if ( (*jt)->shortInformationPriority() > pPlugin->shortInformationPriority() )
                        break;
            }
            // if such plugin was found move the new plugin in front of the other
            if (jt != shownPlugins.end())
            {
                  int sectionOther = _shortInformationColumn[*jt];
                  int indexOther = _pPackageView->header()->mapToIndex(sectionOther);
                  int sectionThis = _shortInformationColumn[pPlugin];
                  _pPackageView->header()->moveSection(sectionThis, indexOther);
                  // insert the name of the plugin before the one found
                  QStringList::iterator kt = _shownShortInformation.find((*jt)->shortInformationCaption());
                  _shownShortInformation.insert(kt, pPlugin->shortInformationCaption());
            }
            else
            {
                  _shownShortInformation.push_back(pPlugin->shortInformationCaption());
            }
      }
}


00520 void PackageSearchImpl::refreshShownAndHidden()
{
      _shownShortInformation.clear();
      QHeader* pHeader = _pPackageView->header();
      for (int section = 0; section < pHeader->count(); ++section)
      {
            // get the real index  assigned to the plugin
            _shownShortInformation.push_back(pHeader->label(pHeader->mapToIndex(section)));
      }
      
      // remove the entries from the _hiddenShortInformation list where no plugin is available for
      for (QStringList::iterator it = _hiddenShortInformation.begin(); 
                  it != _hiddenShortInformation.end(); )
      // don't increment the iterator in the loop header as this is done inside
      {
            ShortInformationPluginContainer::iterator jt = find_if(_shortInformationPlugins.begin(), 
                  _shortInformationPlugins.end(), ShortInformationCaptionEquals(*it));
            if (jt == _shortInformationPlugins.end())
            {
                  // remove the entry from the hidden ones, making sure that 
                  // and point to the next entry
                  it = _hiddenShortInformation.erase(it);
            }
            else
                  ++it;
      }
}


}     // unnamed namespace

void PackageSearchImpl::onClearSearch()
{
//    lockUpdate();
      for (
            SearchPluginContainer::iterator it = _searchPlugins.begin();
            it != _searchPlugins.end();
            ++it
      )
            (*it)->clearSearch();
//    unlockUpdate();
}


bool PackageSearchImpl::FilterPackages::operator()(int packageID)
{
      return _pPlugin->filterPackage(packageID);
}


00570 void PackageSearchImpl::onSearchChanged(NPlugin::SearchPlugin* pPlugin)
{
      reportBusy(0, tr("Evaluating searches"));
      using namespace NPlugin;
      Tagcoll::OpSet<int> result;
      bool first = true;      // keeps track if this is the first search which produces results
      // evaluate plugins which do not uses filter technique
      for (SearchPluginContainer::iterator it = _searchPlugins.begin(); it != _searchPlugins.end(); ++it)
      {
            SearchPlugin* pPlugin = *it;
            if (!pPlugin->isInactive())
            {
                  if (!pPlugin->usesFilterTechnique())
                  {
                        if (first)
                        {
                              result = pPlugin->searchResult();
                              first = false;
                        }
                        else
                              result ^= pPlugin->searchResult();  // create the intersection
                  }
            }
      }
      // filter the resulting packages through the filter plugins
      for (SearchPluginContainer::iterator it = _searchPlugins.begin(); it != _searchPlugins.end(); ++it)
      {
            SearchPlugin* pPlugin = *it;
            if (!pPlugin->isInactive())
            {
                  // if we had no search which returned a result set
                  if (first) 
                  {
                        // the result set are all packages available
                        for (set<string>::const_iterator it = _packages.begin(); it != _packages.end(); ++it)
                              result.insert(_pHandleMaker->getHandle(*it));
                        first = false;
                  }
                  if (pPlugin->usesFilterTechnique())
                  {
                        Tagcoll::OpSet<int> newResult;
                        FilterPackages fp(pPlugin);
                        // copy the packages which are matched by the package filter to newResult
                        NExtStd::copy_if( result.begin(), result.end(), inserter(newResult, newResult.begin()), fp );
                        swap(newResult, result);
                  }
            }
      }
      // if at least one search was active
      if (!first)
            setPackagesFound(result.size());
      else
      {
            setPackagesFound(-1);
            result.clear();
      }
      updateShortInformation(result);
      reportReady(0);
}


00631 void PackageSearchImpl::updateShortInformation(Tagcoll::OpSet<int>& packages)
{
      int lastPackageId = -1; // it seems like -1 is no valid package id (or seldom used..)
      // if a package is selected
      if ( !_currentPackage.isEmpty() )
            lastPackageId = handleMaker().getHandle(toString(_currentPackage));
      // this pointer holds the new item for the formerly selected package, 
      // 0 if the package is not in the new result
      QListViewItem* pSelectItem = 0;
      _pPackageView->clear();
      for (Tagcoll::OpSet<int>::iterator it = packages.begin(); it != packages.end(); ++it)
      {
            int packageId = *it;
            // add the item with its name
            QListViewItem* pItem = new PackageListViewItem(_pPackageView, packageId);
            //, toQString(handleMaker().getItem(packageId))
            if (lastPackageId == packageId)
                  pSelectItem = pItem;
            // iterate all shown columns
            for ( map<NPlugin::ShortInformationPlugin*, int>::iterator jt = _shortInformationColumn.begin();
                  jt != _shortInformationColumn.end(); ++jt)
            {
                  try 
                  {
                        NPlugin::ShortInformationPlugin* pPlugin = jt->first;
                        pItem->setText( jt->second, pPlugin->shortInformationText(packageId) );
                  }
                  // simply ignore it if the package was not available for this plugin
                  catch (NPlugin::PackageNotFoundException& e) {}
            }
      }
      if (pSelectItem)
      {
            _pPackageView->ensureItemVisible(pSelectItem);
            _pPackageView->setSelected(pSelectItem, true);
      }
      // select the first item of the site to be shown
      else if (_pPackageView->firstChild())
      {
            _pPackageView->setSelected(_pPackageView->firstChild(), true);
      }

}

00675 void PackageSearchImpl::showPackageInformation(const QString & package)
{
      // if the package to be shown is not selected, deselect it
      QListViewItem* pSelected = _pPackageView->selectedItem();
      
      if ( pSelected && package != pSelected->text(0))
            _pPackageView->clearSelection();
      _pDetailsView->clear();
      int packageID = handleMaker().getHandle(toString(package));
      for ( InformationPluginContainer::iterator it = _informationPlugins.begin();
            it != _informationPlugins.end(); ++it )
      {
            NPlugin::InformationPlugin* pPlugin = (*it);
            if (package.isEmpty())
            {
                  pPlugin->clearInformationWidget();
            }
            else
            {
                  if ( pPlugin->offersInformationText())
                  {
                        try 
                        {
                              _pDetailsView->setText(_pDetailsView->text() + pPlugin->informationText(packageID));
                        }
                        // simply ignore it if the package was not available for this plugin
                        catch (NPlugin::PackageNotFoundException& e) {}
                  }
                  if (_pInformationContainer->currentPage() == pPlugin->informationWidget())
                  // show the page only if it is currenly active
                        pPlugin->updateInformationWidget(packageID);
            }
      }
}

00710 void PackageSearchImpl::addMenuEntry( pair<QString, QAction*> menuEntry )
{
      if (menuEntry.first == "System")
      {
            menuEntry.second->addTo(_pSystemMenu);
      }
      else  // this is not exactly what I wanted, only to realize the problem later...
      {
            QPopupMenu* pMenu = new QPopupMenu();
            menuEntry.second->addTo(pMenu);
            menuBar()->insertItem(menuEntry.first, pMenu);
      }
}

00724 void PackageSearchImpl::onInformationPageChanged( QWidget * pPage )
{
      if (_currentPackage.isEmpty())      // if no package was selected
            return;
      int packageID = handleMaker().getHandle(toString(_currentPackage));
      for (
            InformationPluginContainer::iterator it = _informationPlugins.begin();
            it != _informationPlugins.end();
            ++it
      )
      {
            if (_pInformationContainer->currentPage() == (*it)->informationWidget())
            // show the page only if it is currenly active
                  (*it)->updateInformationWidget(packageID);
      }
}

00741 void PackageSearchImpl::onControlPlugins()
{
      _pPluginManager->showControlDialog(this);
}

00746 void PackageSearchImpl::onPluginSettings()
{
      _pPluginManager->showSettingsDialog(this);
}

void PackageSearchImpl::saveSettings()
{
      NXml::XmlData xmlData("packagesearch");
      QDomElement root = xmlData.root();
      xmlData.addAttribute(root, QString("0.2"), "settingsVersion");
      
      
      QDomElement window = xmlData.addElement(xmlData.root(), "geometry");
      xmlData.addAttribute(window, width(), "width");
      xmlData.addAttribute(window, height(), "height");
      QValueList<int> sizes = _pHSplitter->sizes();
      xmlData.addAttribute(window, sizes[0], "hSplitterSize1");
      xmlData.addAttribute(window, sizes[1], "hSplitterSize2");

      sizes = _pUpperVSplitter->sizes();
      xmlData.addAttribute(window, sizes[0], "upperVSplitterSize1");
      xmlData.addAttribute(window, sizes[1], "upperVSplitterSize2");

      sizes = _pLowerVSplitter->sizes();
      xmlData.addAttribute(window, sizes[0], "lowerVSplitterSize1");
      xmlData.addAttribute(window, sizes[1], "lowerVSplitterSize2");

      QDomElement shownShortInformation = xmlData.addElement(xmlData.root(), "shownShortInformation");
      xmlData.addText(shownShortInformation, "shortInformation", _shownShortInformation);
      QDomElement hiddenShortInformation = xmlData.addElement(xmlData.root(), "hiddenShortInformation");
      xmlData.addText(hiddenShortInformation, "shortInformation", _hiddenShortInformation);

      _pPluginManager->saveSettings(xmlData, root);
      if ( !xmlData.writeFile(_settingsFilename) )
            reportError(tr("Unable to write settings"), tr("Unable to write settings to") +
                  _settingsFilename + "\nPersonal settings were not saved.");
}

void PackageSearchImpl::loadSettings()
{
      NXml::XmlData xmlData;
      if (!xmlData.loadFile(_settingsFilename))
            return;
      QDomElement element = NXml::getFirstElement(xmlData.root().firstChild());

      
      if (element.tagName() == "geometry")
      {
            uint width;
            uint height;
            NXml::getAttribute(element, width, "width", 500);
            NXml::getAttribute(element, height, "height", 500);
            
            QValueList<int> sizes;
            int size;
            NXml::getAttribute(element, size, "hSplitterSize1", height/2);
            sizes.push_back(size);
            NXml::getAttribute(element, size, "hSplitterSize2", height/2);
            sizes.push_back(size);
            _pHSplitter->setSizes(sizes);
            
            sizes.clear();
            NXml::getAttribute(element, size, "upperVSplitterSize1", width/2);
            sizes.push_back(size);
            NXml::getAttribute(element, size, "upperVSplitterSize2", width/2);
            sizes.push_back(size);
            _pUpperVSplitter->setSizes(sizes);
            
            sizes.clear();
            NXml::getAttribute(element, size, "lowerVSplitterSize1", width/2);
            sizes.push_back(size);
            NXml::getAttribute(element, size, "lowerVSplitterSize2", width/2);
            sizes.push_back(size);
            _pLowerVSplitter->setSizes(sizes);
            
            element = NXml::getNextElement(element);
            
            resize(width, height);
      }

      
      if (element.tagName() == "shownShortInformation")
      {
            _shownShortInformation = NXml::getTextList(element);
            element = NXml::getNextElement(element);
      }
      if (element.tagName() == "hiddenShortInformation")
      {
            _hiddenShortInformation = NXml::getTextList(element);
            element = NXml::getNextElement(element);  
      }
      _pPluginManager->loadSettings(xmlData, element);
}


00841 void PackageSearchImpl::closeEvent(QCloseEvent* pE)
{
      saveSettings();
      pE->accept();
}


00848 void PackageSearchImpl::onPackageViewContextMenu(QListViewItem* pItem, const QPoint& pos)
{
      QPopupMenu menu(_pPackageView);
      if (pItem)
      {
            menu.insertItem(tr("Create apt-get line and copy to clipboard"), 0);
      }
      menu.insertItem(tr("Customize columns"), 1);
      switch (menu.exec(pos))
      {
            case 0:
            {
                  QClipboard *pCb = QApplication::clipboard();
                  pCb->setText("apt-get install "+pItem->text(0), QClipboard::Clipboard);
                  pCb->setText("apt-get install "+pItem->text(0), QClipboard::Selection);
                  break;
            }
            case 1:
            {
                  ColumnControlDlg dlg;
                  refreshShownAndHidden();
                  
                  /** @brief This maps the caption of the short information plugins to the 
                  * column where they are displayed.
                  */
                  map<QString, NPlugin::ShortInformationPlugin*> captionToPlugin;
                  for (ShortInformationPluginContainer::const_iterator it = _shortInformationPlugins.begin(); 
                        it != _shortInformationPlugins.end(); ++it)
                  {
                        captionToPlugin.insert( make_pair((*it)->shortInformationCaption(), *it) );
                  }
                  dlg.setContent(_shownShortInformation, _hiddenShortInformation);
                  if (dlg.exec() == QDialog::Accepted)
                  {
                        _shortInformationColumn.clear();    
                        _shownShortInformation = dlg.getShown();
                        _hiddenShortInformation = dlg.getHidden();
                        updateShortInformationPluginGui();
                        // request an update of the columns
                        onSearchChanged(0);
                  }
                  break;
            }
            default:
                  break;
      }
}




Generated by  Doxygen 1.6.0   Back to index