Logo Search packages:      
Sourcecode: tagcolledit version File versions  Download package

TagcollDocument.cc

/*
 * Tagged Collection document for a Document-View editing architecture
 *
 * Copyright (C) 2003,2004,2005  Enrico Zini <enrico@debian.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "TagcollDocument.h"

#include <tagcoll/Filter.h>
#include <tagcoll/Implications.h>
#include <tagcoll/DerivedTags.h> 
#include <tagcoll/InputMerger.h>
#include <tagcoll/ItemGrouper.h>
#include <tagcoll/TextFormat.h>
#include <tagcoll/Expression.h>
#include <tagcoll/StdioParserInput.h>
#include <tagcoll/StringParserInput.h>

#include "Environment.h"
#include "Serializer.h"

#include <errno.h>

using namespace std;
using namespace Tagcoll;

const char* fn_tagdb = "/var/lib/debtags/package-tags";
const char* fn_impls = "/var/lib/debtags/implications";
const char* fn_deriv = "/var/lib/debtags/derived-tags";

template<class T>
void TagcollDocument<T>::do_changed()
{
      _signal_changed.emit();
}

template<class T>
void TagcollDocument<T>::do_filename_changed()
{
      _signal_filename_changed.emit();
}

template<class T>
bool TagcollDocument<T>::canUndo() const
{
      return _undoTail > 0;
}

template<class T>
bool TagcollDocument<T>::canRedo() const
{
      return _undoTail < _undoBuffer.size();
}

template<class T>
void TagcollDocument<T>::undo()
{
      if (!canUndo())
            return;

      debug("Pre undo: tail: %d, size: %d\n", _undoTail, _undoBuffer.size());
      
      _undoTail--;
      _collection.applyChange(_undoBuffer[_undoTail]);
      _undoBuffer[_undoTail] = _undoBuffer[_undoTail].getReverse();

      debug("Post undo: tail: %d, size: %d\n", _undoTail, _undoBuffer.size());

      do_changed();
}

template<class T>
void TagcollDocument<T>::redo()
{
      if (!canRedo())
            return;

      debug("Pre redo: tail: %d, size: %d\n", _undoTail, _undoBuffer.size());

      _collection.applyChange(_undoBuffer[_undoTail]);
      _undoBuffer[_undoTail] = _undoBuffer[_undoTail].getReverse();
      _undoTail++;

      debug("Post redo: tail: %d, size: %d\n", _undoTail, _undoBuffer.size());

      do_changed();
}

template<class T>
void TagcollDocument<T>::applyChange(const PatchList<T, Tag>& change)
{
      _collection.applyChange(change);
      
      if (1 /*reverse != change*/)
      {
            debug("Pre change: tail: %d, size: %d\n", _undoTail, _undoBuffer.size());

            // Push the reverse change in the undo buffer
            if (_undoTail == _undoBuffer.size())
            {
                  _undoBuffer.push_back(change.getReverse());
                  _undoTail++;
            }
            else
            {
                  _undoBuffer[_undoTail++] = change.getReverse();
                  _undoBuffer.resize(_undoTail);
            }

            debug("Post change: tail: %d, size: %d\n", _undoTail, _undoBuffer.size());
                  
            do_changed();
      } else
            debug("Change had no effect\n");
}

template<class T>
void TagcollDocument<T>::load(const string& file)
{
      Converter<string, T> toitems;
      Converter<string, Tag> totags(_facets);
      if (file == "-")
      {
            StdioParserInput in(stdin, "<stdin>");
            TextFormat<T, Tag>::parse(toitems, totags, in, _collection);
      }
      else
      {
            StdioParserInput in(file);
            TextFormat<T, Tag>::parse(toitems, totags, in, _collection);
      }
      _undoBuffer.clear();
      _undoTail = 0;
      _fileName = file;

      do_filename_changed();
      do_changed();
}

template<class T>
void TagcollDocument<T>::loadDebtags()
{
      load(fn_tagdb);
}

template<class T>
void TagcollDocument<T>::save(const std::string& file)
{
      FILE* out = fopen(file.c_str(), "wt");
      if (!out)
            throw FileException(errno, "opening file " + file);

      // Output the collection, grouping the items
      Converter<T, string> fromitems;
      Converter<Tag, string> fromtags;
      ItemGrouper<T, Tag> grouper;
      output(grouper);

      TextFormat<T, Tag> writer(fromitems, fromtags, out);
      grouper.output(writer);

      fclose(out);

      if (file != _fileName)
      {
            _fileName = file;
            do_filename_changed();
      }
}

template<class ITEM>
void TagcollDocument<ITEM>::output(Consumer<ITEM, Tag>& consumer)
{
      collection().output(consumer);
}

template class TagcollDocument<std::string>;

// vim:set ts=4 sw=4:

Generated by  Doxygen 1.6.0   Back to index