<commit_before>#include <sstream>

#include "StorageFlattening.h"
#include "IRMutator.h"
#include "IROperator.h"
#include "Scope.h"
#include "Bounds.h"
#include "Parameter.h"

namespace Halide {
namespace Internal {

using std::ostringstream;
using std::string;
using std::vector;
using std::map;
using std::pair;
using std::set;

namespace {

class FlattenDimensions : public IRMutator {
public:
    FlattenDimensions(const map<string, pair<Function, int>> &e, const Target &t)
        : env(e), target(t) {}
    Scope<int> scope;
private:
    const map<string, pair<Function, int>> &env;
    const Target ⌖
    Scope<int> realizations;

    Expr flatten_args(const string &name, const vector<Expr> &args) {
        bool internal = realizations.contains(name);
        Expr idx = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
        vector<Expr> mins(args.size()), strides(args.size());

        for (size_t i = 0; i < args.size(); i++) {
            string dim = std::to_string(i);
            string stride_name = name + ".stride." + dim;
            string min_name = name + ".min." + dim;
            string stride_name_constrained = stride_name + ".constrained";
            string min_name_constrained = min_name + ".constrained";
            if (scope.contains(stride_name_constrained)) {
                stride_name = stride_name_constrained;
            }
            if (scope.contains(min_name_constrained)) {
                min_name = min_name_constrained;
            }
            strides[i] = Variable::make(Int(32), stride_name);
            mins[i] = Variable::make(Int(32), min_name);
        }

        if (internal) {
            // f(x, y) -> f[(x-xmin)*xstride + (y-ymin)*ystride] This
            // strategy makes sense when we expect x to cancel with
            // something in xmin.  We use this for internal allocations
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i] - mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += (args[i] - mins[i]) * strides[i];
                }
            }
        } else {
            // f(x, y) -> f[x*stride + y*ystride - (xstride*xmin +
            // ystride*ymin)]. The idea here is that the last term
            // will be pulled outside the inner loop. We use this for
            // external buffers, where the mins and strides are likely
            // to be symbolic
            Expr base = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i]) * cast<int64_t>(strides[i]);
                    base += cast<int64_t>(mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += args[i] * strides[i];
                    base += mins[i] * strides[i];
                }
            }
            idx -= base;
        }

        return idx;
    }

    using IRMutator::visit;

    void visit(const Realize *op) {
        realizations.push(op->name, 0);

        Stmt body = mutate(op->body);

        // Compute the size
        std::vector<Expr> extents;
        for (size_t i = 0; i < op->bounds.size(); i++) {
            extents.push_back(op->bounds[i].extent);
            extents[i] = mutate(extents[i]);
        }
        Expr condition = mutate(op->condition);

        realizations.pop(op->name);

        vector<int> storage_permutation;
        {
            auto iter = env.find(op->name);
            Function f = iter->second.first;
            internal_assert(iter != env.end()) << "Realize node refers to function not in environment.\n";
            const vector<StorageDim> &storage_dims = f.schedule().storage_dims();
            const vector<string> &args = f.args();
            for (size_t i = 0; i < storage_dims.size(); i++) {
                for (size_t j = 0; j < args.size(); j++) {
                    if (args[j] == storage_dims[i].var) {
                        storage_permutation.push_back((int)j);
                        Expr alignment = storage_dims[i].alignment;
                        if (alignment.defined()) {
                            extents[j] = ((extents[j] + alignment - 1)/alignment)*alignment;
                        }
                    }
                }
                internal_assert(storage_permutation.size() == i+1);
            }
        }

        internal_assert(storage_permutation.size() == op->bounds.size());

        stmt = body;
        internal_assert(op->types.size() == 1);

        // Make the names for the mins, extents, and strides
        int dims = op->bounds.size();
        vector<string> min_name(dims), extent_name(dims), stride_name(dims);
        for (int i = 0; i < dims; i++) {
            string d = std::to_string(i);
            min_name[i] = op->name + ".min." + d;
            stride_name[i] = op->name + ".stride." + d;
            extent_name[i] = op->name + ".extent." + d;
        }
        vector<Expr> min_var(dims), extent_var(dims), stride_var(dims);
        for (int i = 0; i < dims; i++) {
            min_var[i] = Variable::make(Int(32), min_name[i]);
            extent_var[i] = Variable::make(Int(32), extent_name[i]);
            stride_var[i] = Variable::make(Int(32), stride_name[i]);
        }

        // Create a buffer_t object for this allocation.
        vector<Expr> args(dims*3 + 2);
        Expr first_elem = Load::make(op->types[0], op->name, 0, BufferPtr(), Parameter());
        args[0] = Call::make(Handle(), Call::address_of, {first_elem}, Call::PureIntrinsic);
        args[1] = make_zero(op->types[0]);
        for (int i = 0; i < dims; i++) {
            args[3*i+2] = min_var[i];
            args[3*i+3] = extent_var[i];
            args[3*i+4] = stride_var[i];
        }
        Expr buf = Call::make(type_of<struct buffer_t *>(), Call::create_buffer_t,
                              args, Call::Intrinsic);
        stmt = LetStmt::make(op->name + ".buffer", buf, stmt);

        // Make the allocation node
        stmt = Allocate::make(op->name, op->types[0], extents, condition, stmt);

        // Compute the strides
        for (int i = (int)op->bounds.size()-1; i > 0; i--) {
            int prev_j = storage_permutation[i-1];
            int j = storage_permutation[i];
            Expr stride = stride_var[prev_j] * extent_var[prev_j];
            stmt = LetStmt::make(stride_name[j], stride, stmt);
        }

        // Innermost stride is one
        if (dims > 0) {
            int innermost = storage_permutation.empty() ? 0 : storage_permutation[0];
            stmt = LetStmt::make(stride_name[innermost], 1, stmt);
        }

        // Assign the mins and extents stored
        for (size_t i = op->bounds.size(); i > 0; i--) {
            stmt = LetStmt::make(min_name[i-1], op->bounds[i-1].min, stmt);
            stmt = LetStmt::make(extent_name[i-1], extents[i-1], stmt);
        }
    }

    void visit(const Provide *op) {
        internal_assert(op->values.size() == 1);

        Expr idx = mutate(flatten_args(op->name, op->args));
        Expr value = mutate(op->values[0]);
        stmt = Store::make(op->name, value, idx, Parameter());
    }

    void visit(const Call *op) {
        if (op->call_type == Call::Halide ||
            op->call_type == Call::Image) {
            internal_assert(op->value_index == 0);
            Expr idx = mutate(flatten_args(op->name, op->args));
            expr = Load::make(op->type, op->name, idx, op->image, op->param);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const LetStmt *let) {
        // Discover constrained versions of things.
        bool constrained_version_exists = ends_with(let->name, ".constrained");
        if (constrained_version_exists) {
            scope.push(let->name, 0);
        }

        IRMutator::visit(let);

        if (constrained_version_exists) {
            scope.pop(let->name);
        }
    }
};

// Realizations, stores, and loads must all be on types that are
// multiples of 8-bits. This really only affects bools
class PromoteToMemoryType : public IRMutator {
    using IRMutator::visit;

    Type upgrade(Type t) {
        return t.with_bits(((t.bits() + 7)/8)*8);
    }

    void visit(const Load *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            expr = Cast::make(op->type, Load::make(t, op->name, mutate(op->index), op->image, op->param));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Store *op) {
        Type t = upgrade(op->value.type());
        if (t != op->value.type()) {
            stmt = Store::make(op->name, Cast::make(t, mutate(op->value)), mutate(op->index), op->param);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Allocate *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            vector<Expr> extents;
            for (Expr e : op->extents) {
                extents.push_back(mutate(e));
            }
            stmt = Allocate::make(op->name, t, extents,
                                  mutate(op->condition), mutate(op->body),
                                  mutate(op->new_expr), op->free_function);
        } else {
            IRMutator::visit(op);
        }
    }
};

// Connect Store nodes to their output buffers
class ConnectOutputBuffers : public IRMutator {
    using IRMutator::visit;

    void visit(const Store *op) {
        Parameter output_buf;
        auto it = env.find(op->name);
        if (it != env.end()) {
            const Function &f = it->second.first;
            int idx = it->second.second;

            // We only want to do this for actual pipeline outputs,
            // even though every Function has an output buffer. Any
            // constraints you set on the output buffer of a Func that
            // isn't actually an output is ignored. This is a language
            // wart.
            if (outputs.count(f.name())) {
                output_buf = f.output_buffers()[idx];
            }
        }

        if (output_buf.defined()) {
            stmt = Store::make(op->name, op->value, op->index, output_buf);
        } else {
            stmt = op;
        }
    }

    const map<string, pair<Function, int>> &env;
    set<string> outputs;

public:
    ConnectOutputBuffers(const std::map<string, pair<Function, int>> &e,
                         const vector<Function> &o) : env(e) {
        for (auto &f : o) {
            outputs.insert(f.name());
        }
    }
};

}  // namespace

Stmt storage_flattening(Stmt s,
                        const vector<Function> &outputs,
                        const map<string, Function> &env,
                        const Target &target) {
    // Make an environment that makes it easier to figure out which
    // Function corresponds to a tuple component. foo.0, foo.1, foo.2,
    // all point to the function foo.
    map<string, pair<Function, int>> tuple_env;
    for (auto p : env) {
        if (p.second.outputs() > 1) {
            for (int i = 0; i < p.second.outputs(); i++) {
                tuple_env[p.first + "." + std::to_string(i)] = {p.second, i};
            }
        } else {
            tuple_env[p.first] = {p.second, 0};
        }
    }

    s = FlattenDimensions(tuple_env, target).mutate(s);
    s = PromoteToMemoryType().mutate(s);
    s = ConnectOutputBuffers(tuple_env, outputs).mutate(s);
    return s;
}

}
}
<commit_msg>cuda fix<commit_after>#include <sstream>

#include "StorageFlattening.h"
#include "IRMutator.h"
#include "IROperator.h"
#include "Scope.h"
#include "Bounds.h"
#include "Parameter.h"

namespace Halide {
namespace Internal {

using std::ostringstream;
using std::string;
using std::vector;
using std::map;
using std::pair;
using std::set;

namespace {

class FlattenDimensions : public IRMutator {
public:
    FlattenDimensions(const map<string, pair<Function, int>> &e, const Target &t)
        : env(e), target(t) {}
    Scope<int> scope;
private:
    const map<string, pair<Function, int>> &env;
    const Target ⌖
    Scope<int> realizations;

    Expr flatten_args(const string &name, const vector<Expr> &args) {
        bool internal = realizations.contains(name);
        Expr idx = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
        vector<Expr> mins(args.size()), strides(args.size());

        for (size_t i = 0; i < args.size(); i++) {
            string dim = std::to_string(i);
            string stride_name = name + ".stride." + dim;
            string min_name = name + ".min." + dim;
            string stride_name_constrained = stride_name + ".constrained";
            string min_name_constrained = min_name + ".constrained";
            if (scope.contains(stride_name_constrained)) {
                stride_name = stride_name_constrained;
            }
            if (scope.contains(min_name_constrained)) {
                min_name = min_name_constrained;
            }
            strides[i] = Variable::make(Int(32), stride_name);
            mins[i] = Variable::make(Int(32), min_name);
        }

        if (internal) {
            // f(x, y) -> f[(x-xmin)*xstride + (y-ymin)*ystride] This
            // strategy makes sense when we expect x to cancel with
            // something in xmin.  We use this for internal allocations
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i] - mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += (args[i] - mins[i]) * strides[i];
                }
            }
        } else {
            // f(x, y) -> f[x*stride + y*ystride - (xstride*xmin +
            // ystride*ymin)]. The idea here is that the last term
            // will be pulled outside the inner loop. We use this for
            // external buffers, where the mins and strides are likely
            // to be symbolic
            Expr base = target.has_feature(Target::LargeBuffers) ? make_zero(Int(64)) : 0;
            for (size_t i = 0; i < args.size(); i++) {
                if (target.has_feature(Target::LargeBuffers)) {
                    idx += cast<int64_t>(args[i]) * cast<int64_t>(strides[i]);
                    base += cast<int64_t>(mins[i]) * cast<int64_t>(strides[i]);
                } else {
                    idx += args[i] * strides[i];
                    base += mins[i] * strides[i];
                }
            }
            idx -= base;
        }

        return idx;
    }

    using IRMutator::visit;

    void visit(const Realize *op) {
        realizations.push(op->name, 0);

        Stmt body = mutate(op->body);

        // Compute the size
        std::vector<Expr> extents;
        for (size_t i = 0; i < op->bounds.size(); i++) {
            extents.push_back(op->bounds[i].extent);
            extents[i] = mutate(extents[i]);
        }
        Expr condition = mutate(op->condition);

        realizations.pop(op->name);

        vector<int> storage_permutation;
        {
            auto iter = env.find(op->name);
            Function f = iter->second.first;
            internal_assert(iter != env.end()) << "Realize node refers to function not in environment.\n";
            const vector<StorageDim> &storage_dims = f.schedule().storage_dims();
            const vector<string> &args = f.args();
            for (size_t i = 0; i < storage_dims.size(); i++) {
                for (size_t j = 0; j < args.size(); j++) {
                    if (args[j] == storage_dims[i].var) {
                        storage_permutation.push_back((int)j);
                        Expr alignment = storage_dims[i].alignment;
                        if (alignment.defined()) {
                            extents[j] = ((extents[j] + alignment - 1)/alignment)*alignment;
                        }
                    }
                }
                internal_assert(storage_permutation.size() == i+1);
            }
        }

        internal_assert(storage_permutation.size() == op->bounds.size());

        stmt = body;
        internal_assert(op->types.size() == 1);

        // Make the names for the mins, extents, and strides
        int dims = op->bounds.size();
        vector<string> min_name(dims), extent_name(dims), stride_name(dims);
        for (int i = 0; i < dims; i++) {
            string d = std::to_string(i);
            min_name[i] = op->name + ".min." + d;
            stride_name[i] = op->name + ".stride." + d;
            extent_name[i] = op->name + ".extent." + d;
        }
        vector<Expr> min_var(dims), extent_var(dims), stride_var(dims);
        for (int i = 0; i < dims; i++) {
            min_var[i] = Variable::make(Int(32), min_name[i]);
            extent_var[i] = Variable::make(Int(32), extent_name[i]);
            stride_var[i] = Variable::make(Int(32), stride_name[i]);
        }

        // Create a buffer_t object for this allocation.
        vector<Expr> args(dims*3 + 2);
        Expr first_elem = Load::make(op->types[0], op->name, 0, BufferPtr(), Parameter());
        args[0] = Call::make(Handle(), Call::address_of, {first_elem}, Call::PureIntrinsic);
        args[1] = make_zero(op->types[0]);
        for (int i = 0; i < dims; i++) {
            args[3*i+2] = min_var[i];
            args[3*i+3] = extent_var[i];
            args[3*i+4] = stride_var[i];
        }
        Expr buf = Call::make(type_of<struct buffer_t *>(), Call::create_buffer_t,
                              args, Call::Intrinsic);
        stmt = LetStmt::make(op->name + ".buffer", buf, stmt);

        // Make the allocation node
        stmt = Allocate::make(op->name, op->types[0], extents, condition, stmt);

        // Compute the strides
        for (int i = (int)op->bounds.size()-1; i > 0; i--) {
            int prev_j = storage_permutation[i-1];
            int j = storage_permutation[i];
            Expr stride = stride_var[prev_j] * extent_var[prev_j];
            stmt = LetStmt::make(stride_name[j], stride, stmt);
        }

        // Innermost stride is one
        if (dims > 0) {
            int innermost = storage_permutation.empty() ? 0 : storage_permutation[0];
            stmt = LetStmt::make(stride_name[innermost], 1, stmt);
        }

        // Assign the mins and extents stored
        for (size_t i = op->bounds.size(); i > 0; i--) {
            stmt = LetStmt::make(min_name[i-1], op->bounds[i-1].min, stmt);
            stmt = LetStmt::make(extent_name[i-1], extents[i-1], stmt);
        }
    }

    void visit(const Provide *op) {
        internal_assert(op->values.size() == 1);

        Expr idx = mutate(flatten_args(op->name, op->args));
        Expr value = mutate(op->values[0]);
        stmt = Store::make(op->name, value, idx, Parameter());
    }

    void visit(const Call *op) {
        if (op->call_type == Call::Halide ||
            op->call_type == Call::Image) {
            internal_assert(op->value_index == 0);
            Expr idx = mutate(flatten_args(op->name, op->args));
            expr = Load::make(op->type, op->name, idx, op->image, op->param);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const LetStmt *let) {
        // Discover constrained versions of things.
        bool constrained_version_exists = ends_with(let->name, ".constrained");
        if (constrained_version_exists) {
            scope.push(let->name, 0);
        }

        IRMutator::visit(let);

        if (constrained_version_exists) {
            scope.pop(let->name);
        }
    }
};

// Realizations, stores, and loads must all be on types that are
// multiples of 8-bits. This really only affects bools
class PromoteToMemoryType : public IRMutator {
    using IRMutator::visit;

    Type upgrade(Type t) {
        return t.with_bits(((t.bits() + 7)/8)*8);
    }

    void visit(const Call *op) {
        if (op->is_intrinsic(Call::address_of)) {
            Expr load = mutate(op->args[0]);
            if (const Cast *cast = load.as<Cast>()) {
                expr = cast->value;
            } else {
                expr = load;
            }
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Load *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            expr = Cast::make(op->type, Load::make(t, op->name, mutate(op->index), op->image, op->param));
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Store *op) {
        Type t = upgrade(op->value.type());
        if (t != op->value.type()) {
            stmt = Store::make(op->name, Cast::make(t, mutate(op->value)), mutate(op->index), op->param);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Allocate *op) {
        Type t = upgrade(op->type);
        if (t != op->type) {
            vector<Expr> extents;
            for (Expr e : op->extents) {
                extents.push_back(mutate(e));
            }
            stmt = Allocate::make(op->name, t, extents,
                                  mutate(op->condition), mutate(op->body),
                                  mutate(op->new_expr), op->free_function);
        } else {
            IRMutator::visit(op);
        }
    }
};

// Connect Store nodes to their output buffers
class ConnectOutputBuffers : public IRMutator {
    using IRMutator::visit;

    void visit(const Store *op) {
        Parameter output_buf;
        auto it = env.find(op->name);
        if (it != env.end()) {
            const Function &f = it->second.first;
            int idx = it->second.second;

            // We only want to do this for actual pipeline outputs,
            // even though every Function has an output buffer. Any
            // constraints you set on the output buffer of a Func that
            // isn't actually an output is ignored. This is a language
            // wart.
            if (outputs.count(f.name())) {
                output_buf = f.output_buffers()[idx];
            }
        }

        if (output_buf.defined()) {
            stmt = Store::make(op->name, op->value, op->index, output_buf);
        } else {
            stmt = op;
        }
    }

    const map<string, pair<Function, int>> &env;
    set<string> outputs;

public:
    ConnectOutputBuffers(const std::map<string, pair<Function, int>> &e,
                         const vector<Function> &o) : env(e) {
        for (auto &f : o) {
            outputs.insert(f.name());
        }
    }
};

}  // namespace

Stmt storage_flattening(Stmt s,
                        const vector<Function> &outputs,
                        const map<string, Function> &env,
                        const Target &target) {
    // Make an environment that makes it easier to figure out which
    // Function corresponds to a tuple component. foo.0, foo.1, foo.2,
    // all point to the function foo.
    map<string, pair<Function, int>> tuple_env;
    for (auto p : env) {
        if (p.second.outputs() > 1) {
            for (int i = 0; i < p.second.outputs(); i++) {
                tuple_env[p.first + "." + std::to_string(i)] = {p.second, i};
            }
        } else {
            tuple_env[p.first] = {p.second, 0};
        }
    }

    s = FlattenDimensions(tuple_env, target).mutate(s);
    s = PromoteToMemoryType().mutate(s);
    s = ConnectOutputBuffers(tuple_env, outputs).mutate(s);
    return s;
}

}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fieldwnd.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2003-04-17 15:09:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FIELDWND_HXX
#define SC_FIELDWND_HXX

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#define MAX_LABELS  256
#define PAGE_SIZE   16      // count of visible fields for scrollbar
#define LINE_SIZE   8       // count of fields per column for scrollbar
#define MAX_FIELDS  8       // maximum count of fields for row/col/data area

#define OWIDTH  PivotGlobal::nObjWidth
#define OHEIGHT PivotGlobal::nObjHeight
#define SSPACE  PivotGlobal::nSelSpace

class ScDPLayoutDlg;
class ScAccessibleDataPilotControl;

//===================================================================

/** Type of content area. */
enum ScDPFieldType
{
    TYPE_ROW,               /// Area for all row fields.
    TYPE_COL,               /// Area for all column fields.
    TYPE_DATA,              /// Area for all data fields.
    TYPE_SELECT             /// Selection area with all fields.
};

//-------------------------------------------------------------------

/** Represents a field area in the DataPilot layout dialog. */
class ScDPFieldWindow : public Control
{
private:
    String                  aName;          /// name of the control, used in Accessibility
    ScDPLayoutDlg*          pDlg;           /// Parent dialog.
    Rectangle               aWndRect;       /// Area rectangle in pixels.
    FixedText*              pFtCaption;     /// FixedText containing the name of the control.
    Point                   aTextPos;       /// Position of the caption text.
    String**                aFieldArr;      /// Pointer to string array of the field names.
    ScDPFieldType           eType;          /// Type of this area.
    Color                   aFaceColor;     /// Color for dialog background.
    Color                   aWinColor;      /// Color for window background.
    Color                   aTextColor;     /// Color for text in buttons.
    Color                   aWinTextColor;  /// Color for text in field windows.
    long                    nFieldSize;     /// Maximum count of fields.
    long                    nFieldCount;    /// Count of existing fields.
    long                    nFieldSelected; /// Currently selected field.

    com::sun::star::uno::WeakReference< ::drafts::com::sun::star::accessibility::XAccessible > xAccessible;
    ScAccessibleDataPilotControl* pAccessible;

    /** Initilize the object. */
    void                    Init();

    /** Reads all needed style settings. */
    void                    GetStyleSettings();

    /** Draws the background. */
    void                    DrawBackground( OutputDevice& rDev );
    /** Draws a field into the specified rectangle. */
    void                    DrawField(
                                OutputDevice& rDev,
                                const Rectangle& rRect,
                                const String& rText,
                                BOOL bSelected );

    /** @return  TRUE, if the field index is inside of the control area. */
    BOOL                    IsValidIndex( long nIndex ) const;
    /** @return  TRUE, if the field with the given index exists. */
    BOOL                    IsExistingIndex( long nIndex ) const;
    /** @return  The new selection index after moving to the given direction. */
    long                    CalcNewFieldIndex( short nDX, short nDY ) const;

    /** Sets selection to the field with index nIndex. */
    void                    SetSelection( long nIndex );
    /** Sets selection to first field. */
    void                    SetSelectionHome();
    /** Sets selection to last field. */
    void                    SetSelectionEnd();
    /** Sets selection to new position relative to current. */
    void                    MoveSelection( USHORT nKeyCode, short nDX, short nDY );

    /** Moves the selected field to nDestIndex. */
    void                    MoveField( long nDestIndex );
    /** Moves the selected field to the given direction. */
    void                    MoveFieldRel( short nDX, short nDY );

protected:
    virtual void            Paint( const Rectangle& rRect );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );
    virtual void            MouseButtonDown( const MouseEvent& rMEvt );
    virtual void            MouseButtonUp( const MouseEvent& rMEvt );
    virtual void            MouseMove( const MouseEvent& rMEvt );
    virtual void            KeyInput( const KeyEvent& rKEvt );
    virtual void            GetFocus();
    virtual void            LoseFocus();
    virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > CreateAccessible();

public:
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                FixedText* pFtFieldCaption );
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                const String& aName );
    virtual                 ~ScDPFieldWindow();

    /** Draws the complete control. */
    void                    Redraw();

    /** @return  The pixel position of a field (without bound check). */
    Point                   GetFieldPosition( long nIndex ) const;
    /** @return  The pixel size of a field. */
    Size                    GetFieldSize() const;

    /** @return  The index of the selected field. */
    inline BOOL             IsEmpty() const             { return nFieldCount == 0; }
    /** @return  The index of the selected field. */
    inline long             GetSelectedField() const    { return nFieldSelected; }
    /** @return  The pixel position of the last possible field. */
    Point                   GetLastPosition() const;

    /** @return  The count of existing fields. */
    long                    GetFieldCount() const       { return nFieldCount; }
    /** Inserts a field to the specified index. */
    void                    AddField( const String& rText, long nNewIndex );
    /** Removes a field from the specified index. */
    void                    DelField( long nDelIndex );
    /** Removes all fields. */
    void                    ClearFields();
    /** Changes the text on an existing field. */
    void                    SetFieldText( const String& rText, long nIndex );
    /** Returns the text of an existing field. */
    const String&           GetFieldText(long nIndex) const;

    /** Inserts a field using the specified pixel position.
        @param rPos  The coordinates to insert the field.
        @param rnIndex  The new index of the field is returned here.
        @return  TRUE, if the field has been created. */
    BOOL                    AddField( const String& rText, const Point& rPos, long& rnIndex );
    /** Calculates the field index at a specific pixel position.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    BOOL                    GetFieldIndex( const Point& rPos, long& rnIndex ) const;
    /** Calculates a field index at a specific pixel position. Returns in every
        case the index of an existing field.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    void                    GetExistingIndex( const Point& rPos, long& rnIndex );

    /** Notifies this control that the offset of the first field has been changed.
        The control has to adjust the selection to keep the same field selected
        on scrolling with scrollbar. */
    void                    ModifySelectionOffset( long nOffsetDiff );
    /** Selects the next field. Called i.e. after moving a field from SELECT area. */
    void                    SelectNext();

    /** @return The name of the control without shortcut. */
    String                  GetName()const              { return aName; }

    /** @return The description of the control which is used for the accessibility objects. */
    String                  GetDescription()const;

    /** Grabs focus and sets new selection. */
    void                    GrabFocusWithSel( long nIndex );

    /** @return The type of the FieldWindow. */
    ScDPFieldType           GetType() const { return eType; }
};

//===================================================================

#endif // SC_FIELDWND_HXX
<commit_msg>INTEGRATION: CWS uaa02 (1.7.24); FILE MERGED 2003/04/22 08:15:03 mt 1.7.24.1: #108656# Moved Accessibility from drafts to final<commit_after>/*************************************************************************
 *
 *  $RCSfile: fieldwnd.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-24 17:16:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FIELDWND_HXX
#define SC_FIELDWND_HXX

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#define MAX_LABELS  256
#define PAGE_SIZE   16      // count of visible fields for scrollbar
#define LINE_SIZE   8       // count of fields per column for scrollbar
#define MAX_FIELDS  8       // maximum count of fields for row/col/data area

#define OWIDTH  PivotGlobal::nObjWidth
#define OHEIGHT PivotGlobal::nObjHeight
#define SSPACE  PivotGlobal::nSelSpace

class ScDPLayoutDlg;
class ScAccessibleDataPilotControl;

//===================================================================

/** Type of content area. */
enum ScDPFieldType
{
    TYPE_ROW,               /// Area for all row fields.
    TYPE_COL,               /// Area for all column fields.
    TYPE_DATA,              /// Area for all data fields.
    TYPE_SELECT             /// Selection area with all fields.
};

//-------------------------------------------------------------------

/** Represents a field area in the DataPilot layout dialog. */
class ScDPFieldWindow : public Control
{
private:
    String                  aName;          /// name of the control, used in Accessibility
    ScDPLayoutDlg*          pDlg;           /// Parent dialog.
    Rectangle               aWndRect;       /// Area rectangle in pixels.
    FixedText*              pFtCaption;     /// FixedText containing the name of the control.
    Point                   aTextPos;       /// Position of the caption text.
    String**                aFieldArr;      /// Pointer to string array of the field names.
    ScDPFieldType           eType;          /// Type of this area.
    Color                   aFaceColor;     /// Color for dialog background.
    Color                   aWinColor;      /// Color for window background.
    Color                   aTextColor;     /// Color for text in buttons.
    Color                   aWinTextColor;  /// Color for text in field windows.
    long                    nFieldSize;     /// Maximum count of fields.
    long                    nFieldCount;    /// Count of existing fields.
    long                    nFieldSelected; /// Currently selected field.

    com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAccessible;
    ScAccessibleDataPilotControl* pAccessible;

    /** Initilize the object. */
    void                    Init();

    /** Reads all needed style settings. */
    void                    GetStyleSettings();

    /** Draws the background. */
    void                    DrawBackground( OutputDevice& rDev );
    /** Draws a field into the specified rectangle. */
    void                    DrawField(
                                OutputDevice& rDev,
                                const Rectangle& rRect,
                                const String& rText,
                                BOOL bSelected );

    /** @return  TRUE, if the field index is inside of the control area. */
    BOOL                    IsValidIndex( long nIndex ) const;
    /** @return  TRUE, if the field with the given index exists. */
    BOOL                    IsExistingIndex( long nIndex ) const;
    /** @return  The new selection index after moving to the given direction. */
    long                    CalcNewFieldIndex( short nDX, short nDY ) const;

    /** Sets selection to the field with index nIndex. */
    void                    SetSelection( long nIndex );
    /** Sets selection to first field. */
    void                    SetSelectionHome();
    /** Sets selection to last field. */
    void                    SetSelectionEnd();
    /** Sets selection to new position relative to current. */
    void                    MoveSelection( USHORT nKeyCode, short nDX, short nDY );

    /** Moves the selected field to nDestIndex. */
    void                    MoveField( long nDestIndex );
    /** Moves the selected field to the given direction. */
    void                    MoveFieldRel( short nDX, short nDY );

protected:
    virtual void            Paint( const Rectangle& rRect );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );
    virtual void            MouseButtonDown( const MouseEvent& rMEvt );
    virtual void            MouseButtonUp( const MouseEvent& rMEvt );
    virtual void            MouseMove( const MouseEvent& rMEvt );
    virtual void            KeyInput( const KeyEvent& rKEvt );
    virtual void            GetFocus();
    virtual void            LoseFocus();
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();

public:
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                FixedText* pFtFieldCaption );
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                const String& aName );
    virtual                 ~ScDPFieldWindow();

    /** Draws the complete control. */
    void                    Redraw();

    /** @return  The pixel position of a field (without bound check). */
    Point                   GetFieldPosition( long nIndex ) const;
    /** @return  The pixel size of a field. */
    Size                    GetFieldSize() const;

    /** @return  The index of the selected field. */
    inline BOOL             IsEmpty() const             { return nFieldCount == 0; }
    /** @return  The index of the selected field. */
    inline long             GetSelectedField() const    { return nFieldSelected; }
    /** @return  The pixel position of the last possible field. */
    Point                   GetLastPosition() const;

    /** @return  The count of existing fields. */
    long                    GetFieldCount() const       { return nFieldCount; }
    /** Inserts a field to the specified index. */
    void                    AddField( const String& rText, long nNewIndex );
    /** Removes a field from the specified index. */
    void                    DelField( long nDelIndex );
    /** Removes all fields. */
    void                    ClearFields();
    /** Changes the text on an existing field. */
    void                    SetFieldText( const String& rText, long nIndex );
    /** Returns the text of an existing field. */
    const String&           GetFieldText(long nIndex) const;

    /** Inserts a field using the specified pixel position.
        @param rPos  The coordinates to insert the field.
        @param rnIndex  The new index of the field is returned here.
        @return  TRUE, if the field has been created. */
    BOOL                    AddField( const String& rText, const Point& rPos, long& rnIndex );
    /** Calculates the field index at a specific pixel position.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    BOOL                    GetFieldIndex( const Point& rPos, long& rnIndex ) const;
    /** Calculates a field index at a specific pixel position. Returns in every
        case the index of an existing field.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    void                    GetExistingIndex( const Point& rPos, long& rnIndex );

    /** Notifies this control that the offset of the first field has been changed.
        The control has to adjust the selection to keep the same field selected
        on scrolling with scrollbar. */
    void                    ModifySelectionOffset( long nOffsetDiff );
    /** Selects the next field. Called i.e. after moving a field from SELECT area. */
    void                    SelectNext();

    /** @return The name of the control without shortcut. */
    String                  GetName()const              { return aName; }

    /** @return The description of the control which is used for the accessibility objects. */
    String                  GetDescription()const;

    /** Grabs focus and sets new selection. */
    void                    GrabFocusWithSel( long nIndex );

    /** @return The type of the FieldWindow. */
    ScDPFieldType           GetType() const { return eType; }
};

//===================================================================

#endif // SC_FIELDWND_HXX
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tphf.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:45:04 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------

#define _TPHF_CXX
#include "scitems.hxx"
#include <sfx2/basedlgs.hxx>
#include <svtools/style.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>

#include "tphf.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "tabvwsh.hxx"
#include "viewdata.hxx"
#include "document.hxx"
#include "tphfedit.hxx"
#include "hfedtdlg.hxx"
#include "styledlg.hxx"
#include "scresid.hxx"

#undef _TPHF_CXX

//==================================================================
// class ScHFPage
//==================================================================

ScHFPage::ScHFPage( Window* pParent, USHORT nResId,
                    const SfxItemSet& rSet, USHORT nSetId )

    :   SvxHFPage   ( pParent, nResId, rSet, nSetId ),
        aBtnEdit    ( this, ScResId( RID_SCBTN_HFEDIT ) ),
        aDataSet    ( *rSet.GetPool(),
                       ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERRIGHT,
                       ATTR_PAGE, ATTR_PAGE, 0 ),
        nPageUsage  ( (USHORT)SVX_PAGE_ALL ),
        pStyleDlg   ( NULL )
{
    SetExchangeSupport();

    SfxViewShell*   pSh = SfxViewShell::Current();
    ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,pSh);
    Point           aPos( aBackgroundBtn.GetPosPixel() );

    aPos.Y() -= 8;
    aBackgroundBtn.SetPosPixel( aPos );

    aPos.Y() += aBackgroundBtn.GetSizePixel().Height();
    aPos.Y() += 4;
    aBtnEdit.SetPosPixel( aPos );
    aBtnEdit.Show();

    aDataSet.Put( rSet );

    if ( pViewSh )
    {
        ScViewData* pViewData = pViewSh->GetViewData();
        ScDocument* pDoc      = pViewData->GetDocument();

        aStrPageStyle = pDoc->GetPageStyle( pViewData->GetTabNo() );
    }

    aBtnEdit.SetClickHdl    ( LINK( this, ScHFPage, BtnHdl ) );
    aTurnOnBox.SetClickHdl  ( LINK( this, ScHFPage, TurnOnHdl ) );

    if ( nId == SID_ATTR_PAGE_HEADERSET )
        aBtnEdit.SetHelpId( HID_SC_HEADER_EDIT );
    else
        aBtnEdit.SetHelpId( HID_SC_FOOTER_EDIT );
}

//------------------------------------------------------------------

__EXPORT ScHFPage::~ScHFPage()
{
}

//------------------------------------------------------------------

void __EXPORT ScHFPage::Reset( const SfxItemSet& rSet )
{
    SvxHFPage::Reset( rSet );
    TurnOnHdl( 0 );
}

//------------------------------------------------------------------

BOOL __EXPORT ScHFPage::FillItemSet( SfxItemSet& rOutSet )
{
    BOOL bResult = SvxHFPage::FillItemSet( rOutSet );

    if ( nId == SID_ATTR_PAGE_HEADERSET )
    {
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_HEADERLEFT ) );
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_HEADERRIGHT ) );
    }
    else
    {
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_FOOTERLEFT ) );
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_FOOTERRIGHT ) );
    }

    return bResult;
}

//------------------------------------------------------------------

void __EXPORT ScHFPage::ActivatePage( const SfxItemSet& rSet )
{
    USHORT              nPageWhich = GetWhich( SID_ATTR_PAGE );
    const SvxPageItem&  rPageItem  = (const SvxPageItem&)
                                     rSet.Get(nPageWhich);

    nPageUsage = rPageItem.GetPageUsage();

    if ( pStyleDlg )
        aStrPageStyle = pStyleDlg->GetStyleSheet().GetName();

    aDataSet.Put( rSet.Get(ATTR_PAGE) );

    SvxHFPage::ActivatePage( rSet );
}

//------------------------------------------------------------------

int __EXPORT ScHFPage::DeactivatePage( SfxItemSet* pSet )
{
    if ( LEAVE_PAGE == SvxHFPage::DeactivatePage( pSet ) )
        if ( pSet )
            FillItemSet( *pSet );

    return LEAVE_PAGE;
}

//------------------------------------------------------------------
// Handler:
//------------------------------------------------------------------

IMPL_LINK( ScHFPage, TurnOnHdl, CheckBox*, EMPTYARG )
{
    SvxHFPage::TurnOnHdl( &aTurnOnBox );

    if ( aTurnOnBox.IsChecked() )
        aBtnEdit.Enable();
    else
        aBtnEdit.Disable();

    return NULL;
}

//------------------------------------------------------------------

IMPL_LINK( ScHFPage, BtnHdl, PushButton*, EMPTYARG )
{
    //  Wenn der Bearbeiten-Dialog direkt aus dem Click-Handler des Buttons
    //  aufgerufen wird, funktioniert im Bearbeiten-Dialog unter OS/2 das
    //  GrabFocus nicht (Bug #41805#).
    //  Mit dem neuen StarView sollte dieser Workaround wieder raus koennen!

    Application::PostUserEvent( LINK( this, ScHFPage, HFEditHdl ) );
    return 0;
}

IMPL_LINK( ScHFPage, HFEditHdl, void*, EMPTYARG )
{
    SfxViewShell*   pViewSh = SfxViewShell::Current();

    if ( !pViewSh )
    {
        DBG_ERROR( "Current ViewShell not found." );
        return NULL;
    }

    if (   aCntSharedBox.IsEnabled()
        && !aCntSharedBox.IsChecked() )
    {
        USHORT nResId = ( nId == SID_ATTR_PAGE_HEADERSET )
                            ? RID_SCDLG_HFED_HEADER
                            : RID_SCDLG_HFED_FOOTER;

        ScHFEditDlg* pDlg
             = new ScHFEditDlg( pViewSh->GetViewFrame(), this,
                                aDataSet, aStrPageStyle, nResId );

        if ( pDlg->Execute() == RET_OK )
        {
            aDataSet.Put( *pDlg->GetOutputItemSet() );
        }

        delete pDlg;
    }
    else
    {
        String              aText;
        SfxSingleTabDialog* pDlg
            = new SfxSingleTabDialog( pViewSh->GetViewFrame(), this,
                                      aDataSet, 42, FALSE );
        BOOL bRightPage =   aCntSharedBox.IsChecked()
                         || ( SVX_PAGE_LEFT != SvxPageUsage(nPageUsage) );

        if ( nId == SID_ATTR_PAGE_HEADERSET )
        {
            aText = ScGlobal::GetRscString( STR_PAGEHEADER );
            if ( bRightPage )
                pDlg->SetTabPage( ScRightHeaderEditPage::Create( pDlg, aDataSet ) );
            else
                pDlg->SetTabPage( ScLeftHeaderEditPage::Create( pDlg, aDataSet ) );
        }
        else
        {
            aText = ScGlobal::GetRscString( STR_PAGEFOOTER );
            if ( bRightPage )
                pDlg->SetTabPage( ScRightFooterEditPage::Create( pDlg, aDataSet ) );
            else
                pDlg->SetTabPage( ScLeftFooterEditPage::Create( pDlg, aDataSet ) );
        }

        SvxNumType eNumType = ((const SvxPageItem&)aDataSet.Get(ATTR_PAGE)).GetNumType();
        ((ScHFEditPage*)pDlg->GetTabPage())->SetNumType(eNumType);

        aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
        aText += ScGlobal::GetRscString( STR_PAGESTYLE );
        aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
        aText += aStrPageStyle;
        aText += ')';

        pDlg->SetText( aText );

        if ( pDlg->Execute() == RET_OK )
        {
            aDataSet.Put( *pDlg->GetOutputItemSet() );
        }

        delete pDlg;
    }

    return NULL;
}

//==================================================================
// class ScHeaderPage
//==================================================================

ScHeaderPage::ScHeaderPage( Window* pParent, const SfxItemSet& rSet )
    : ScHFPage( pParent, RID_SVXPAGE_HEADER, rSet, SID_ATTR_PAGE_HEADERSET )
{
}

//------------------------------------------------------------------

SfxTabPage* __EXPORT ScHeaderPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
{
    return ( new ScHeaderPage( pParent, rCoreSet ) );
}

//------------------------------------------------------------------

USHORT* __EXPORT ScHeaderPage::GetRanges()
{
    return SvxHeaderPage::GetRanges();
}

//==================================================================
// class ScFooterPage
//==================================================================

ScFooterPage::ScFooterPage( Window* pParent, const SfxItemSet& rSet )
    : ScHFPage( pParent, RID_SVXPAGE_FOOTER, rSet, SID_ATTR_PAGE_FOOTERSET )
{
}

//------------------------------------------------------------------

SfxTabPage* __EXPORT ScFooterPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
{
    return ( new ScFooterPage( pParent, rCoreSet ) );
}

//------------------------------------------------------------------

USHORT* __EXPORT ScFooterPage::GetRanges()
{
    return SvxHeaderPage::GetRanges();
}

<commit_msg>edit button is right of background button instead of below it<commit_after>/*************************************************************************
 *
 *  $RCSfile: tphf.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: nn $ $Date: 2001-03-01 14:10:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------

#define _TPHF_CXX
#include "scitems.hxx"
#include <sfx2/basedlgs.hxx>
#include <svtools/style.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>

#include "tphf.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "tabvwsh.hxx"
#include "viewdata.hxx"
#include "document.hxx"
#include "tphfedit.hxx"
#include "hfedtdlg.hxx"
#include "styledlg.hxx"
#include "scresid.hxx"

#undef _TPHF_CXX

//==================================================================
// class ScHFPage
//==================================================================

ScHFPage::ScHFPage( Window* pParent, USHORT nResId,
                    const SfxItemSet& rSet, USHORT nSetId )

    :   SvxHFPage   ( pParent, nResId, rSet, nSetId ),
        aBtnEdit    ( this, ScResId( RID_SCBTN_HFEDIT ) ),
        aDataSet    ( *rSet.GetPool(),
                       ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERRIGHT,
                       ATTR_PAGE, ATTR_PAGE, 0 ),
        nPageUsage  ( (USHORT)SVX_PAGE_ALL ),
        pStyleDlg   ( NULL )
{
    SetExchangeSupport();

    SfxViewShell*   pSh = SfxViewShell::Current();
    ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,pSh);
    Point           aPos( aBackgroundBtn.GetPosPixel() );

    // aBackgroundBtn position not changed anymore

    aPos.X() += aBackgroundBtn.GetSizePixel().Width();
    aPos.X() += 6;
    aBtnEdit.SetPosPixel( aPos );
    aBtnEdit.Show();

    aDataSet.Put( rSet );

    if ( pViewSh )
    {
        ScViewData* pViewData = pViewSh->GetViewData();
        ScDocument* pDoc      = pViewData->GetDocument();

        aStrPageStyle = pDoc->GetPageStyle( pViewData->GetTabNo() );
    }

    aBtnEdit.SetClickHdl    ( LINK( this, ScHFPage, BtnHdl ) );
    aTurnOnBox.SetClickHdl  ( LINK( this, ScHFPage, TurnOnHdl ) );

    if ( nId == SID_ATTR_PAGE_HEADERSET )
        aBtnEdit.SetHelpId( HID_SC_HEADER_EDIT );
    else
        aBtnEdit.SetHelpId( HID_SC_FOOTER_EDIT );
}

//------------------------------------------------------------------

__EXPORT ScHFPage::~ScHFPage()
{
}

//------------------------------------------------------------------

void __EXPORT ScHFPage::Reset( const SfxItemSet& rSet )
{
    SvxHFPage::Reset( rSet );
    TurnOnHdl( 0 );
}

//------------------------------------------------------------------

BOOL __EXPORT ScHFPage::FillItemSet( SfxItemSet& rOutSet )
{
    BOOL bResult = SvxHFPage::FillItemSet( rOutSet );

    if ( nId == SID_ATTR_PAGE_HEADERSET )
    {
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_HEADERLEFT ) );
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_HEADERRIGHT ) );
    }
    else
    {
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_FOOTERLEFT ) );
        rOutSet.Put( aDataSet.Get( ATTR_PAGE_FOOTERRIGHT ) );
    }

    return bResult;
}

//------------------------------------------------------------------

void __EXPORT ScHFPage::ActivatePage( const SfxItemSet& rSet )
{
    USHORT              nPageWhich = GetWhich( SID_ATTR_PAGE );
    const SvxPageItem&  rPageItem  = (const SvxPageItem&)
                                     rSet.Get(nPageWhich);

    nPageUsage = rPageItem.GetPageUsage();

    if ( pStyleDlg )
        aStrPageStyle = pStyleDlg->GetStyleSheet().GetName();

    aDataSet.Put( rSet.Get(ATTR_PAGE) );

    SvxHFPage::ActivatePage( rSet );
}

//------------------------------------------------------------------

int __EXPORT ScHFPage::DeactivatePage( SfxItemSet* pSet )
{
    if ( LEAVE_PAGE == SvxHFPage::DeactivatePage( pSet ) )
        if ( pSet )
            FillItemSet( *pSet );

    return LEAVE_PAGE;
}

//------------------------------------------------------------------
// Handler:
//------------------------------------------------------------------

IMPL_LINK( ScHFPage, TurnOnHdl, CheckBox*, EMPTYARG )
{
    SvxHFPage::TurnOnHdl( &aTurnOnBox );

    if ( aTurnOnBox.IsChecked() )
        aBtnEdit.Enable();
    else
        aBtnEdit.Disable();

    return NULL;
}

//------------------------------------------------------------------

IMPL_LINK( ScHFPage, BtnHdl, PushButton*, EMPTYARG )
{
    //  Wenn der Bearbeiten-Dialog direkt aus dem Click-Handler des Buttons
    //  aufgerufen wird, funktioniert im Bearbeiten-Dialog unter OS/2 das
    //  GrabFocus nicht (Bug #41805#).
    //  Mit dem neuen StarView sollte dieser Workaround wieder raus koennen!

    Application::PostUserEvent( LINK( this, ScHFPage, HFEditHdl ) );
    return 0;
}

IMPL_LINK( ScHFPage, HFEditHdl, void*, EMPTYARG )
{
    SfxViewShell*   pViewSh = SfxViewShell::Current();

    if ( !pViewSh )
    {
        DBG_ERROR( "Current ViewShell not found." );
        return NULL;
    }

    if (   aCntSharedBox.IsEnabled()
        && !aCntSharedBox.IsChecked() )
    {
        USHORT nResId = ( nId == SID_ATTR_PAGE_HEADERSET )
                            ? RID_SCDLG_HFED_HEADER
                            : RID_SCDLG_HFED_FOOTER;

        ScHFEditDlg* pDlg
             = new ScHFEditDlg( pViewSh->GetViewFrame(), this,
                                aDataSet, aStrPageStyle, nResId );

        if ( pDlg->Execute() == RET_OK )
        {
            aDataSet.Put( *pDlg->GetOutputItemSet() );
        }

        delete pDlg;
    }
    else
    {
        String              aText;
        SfxSingleTabDialog* pDlg
            = new SfxSingleTabDialog( pViewSh->GetViewFrame(), this,
                                      aDataSet, 42, FALSE );
        BOOL bRightPage =   aCntSharedBox.IsChecked()
                         || ( SVX_PAGE_LEFT != SvxPageUsage(nPageUsage) );

        if ( nId == SID_ATTR_PAGE_HEADERSET )
        {
            aText = ScGlobal::GetRscString( STR_PAGEHEADER );
            if ( bRightPage )
                pDlg->SetTabPage( ScRightHeaderEditPage::Create( pDlg, aDataSet ) );
            else
                pDlg->SetTabPage( ScLeftHeaderEditPage::Create( pDlg, aDataSet ) );
        }
        else
        {
            aText = ScGlobal::GetRscString( STR_PAGEFOOTER );
            if ( bRightPage )
                pDlg->SetTabPage( ScRightFooterEditPage::Create( pDlg, aDataSet ) );
            else
                pDlg->SetTabPage( ScLeftFooterEditPage::Create( pDlg, aDataSet ) );
        }

        SvxNumType eNumType = ((const SvxPageItem&)aDataSet.Get(ATTR_PAGE)).GetNumType();
        ((ScHFEditPage*)pDlg->GetTabPage())->SetNumType(eNumType);

        aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
        aText += ScGlobal::GetRscString( STR_PAGESTYLE );
        aText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " ));
        aText += aStrPageStyle;
        aText += ')';

        pDlg->SetText( aText );

        if ( pDlg->Execute() == RET_OK )
        {
            aDataSet.Put( *pDlg->GetOutputItemSet() );
        }

        delete pDlg;
    }

    return NULL;
}

//==================================================================
// class ScHeaderPage
//==================================================================

ScHeaderPage::ScHeaderPage( Window* pParent, const SfxItemSet& rSet )
    : ScHFPage( pParent, RID_SVXPAGE_HEADER, rSet, SID_ATTR_PAGE_HEADERSET )
{
}

//------------------------------------------------------------------

SfxTabPage* __EXPORT ScHeaderPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
{
    return ( new ScHeaderPage( pParent, rCoreSet ) );
}

//------------------------------------------------------------------

USHORT* __EXPORT ScHeaderPage::GetRanges()
{
    return SvxHeaderPage::GetRanges();
}

//==================================================================
// class ScFooterPage
//==================================================================

ScFooterPage::ScFooterPage( Window* pParent, const SfxItemSet& rSet )
    : ScHFPage( pParent, RID_SVXPAGE_FOOTER, rSet, SID_ATTR_PAGE_FOOTERSET )
{
}

//------------------------------------------------------------------

SfxTabPage* __EXPORT ScFooterPage::Create( Window* pParent, const SfxItemSet& rCoreSet )
{
    return ( new ScFooterPage( pParent, rCoreSet ) );
}

//------------------------------------------------------------------

USHORT* __EXPORT ScFooterPage::GetRanges()
{
    return SvxHeaderPage::GetRanges();
}

<|endoftext|>


<commit_before><commit_msg>coverity#708099 unused mTypeClass member<commit_after><|endoftext|>


<commit_before>#include<iostream>
#include<fstream>
#include<string>
#include<vector>
/*to do:
	finish prerequisites function: figure out every topic you need to learn before you can learn a specified topic
	figure out what other functions might be useful
	populate datastructures.txt more, change name to something better like programming.txt or w/e
	implement student files(just a list of known topics)
	implement interface for users to specify a student file so knows is automatically run with it
*/
struct rdnode {
	public:
	std::string topic;
	std::vector<rdnode*> parents;
	std::vector<rdnode*> children;
	bool knows;
};

struct database {
	std::vector<rdnode*> nodes;
};

void learnable (database* points) {
	rdnode* temp;
	std::vector<rdnode*> learn;
	bool learnability = true;
	for (int count = 0; count < points->nodes.size(); count++) {
		learnability = true;
		temp = points->nodes[count];
		if (temp->knows == false) {
			rdnode* parent;
			for (int counter = 0; counter < temp->parents.size() && learnability == true; counter++) {
				parent = temp->parents[counter];
				if (parent->knows == false) {
					learnability = false;
				}
			}
			if (learnability == true) {
				learn.push_back(temp);
			}
		}
	}
	std::cout << "You can learn: " << learn.size() << " topics." << std::endl;
	for (int count = 0; count < learn.size(); count++) {
		temp = learn[count];
		std::cout << temp->topic << " " << std::endl;
	}
}

void depopulate(database* points) {
	rdnode* delnode;
	for (int count = 0; count < points->nodes.size(); count++) {
		delnode = points->nodes[count];
		delete delnode;
	}
	delete points;
}

rdnode* makenode(std::string topicname, database* points) {
	rdnode* tempnode;
	for (int count = 0; count < points->nodes.size(); count++) {
		tempnode = points->nodes[count];
		if (tempnode->topic == topicname) {
			return tempnode;
		}
	}
	rdnode* newnode = new rdnode;
	newnode->topic = topicname;
	newnode->knows = false;
	points->nodes.push_back(newnode);
	return newnode;
}

void knowsr(rdnode* temp) {
	rdnode* thing;
	bool ask = true;
	for (int count = 0; count < temp->children.size(); count++) {
		thing = temp->children[count];
		rdnode* third;
		for (int counter = 0; count < thing->parents.size(); count++) {
			third = thing->parents[count];
			if (third->knows == false) {
				ask = false;
			}
		}
		if (ask == true) {
			std::cout << "Do you understand " << thing->topic << " (y/n)?" << std::endl;
			char answer;
			std::cin >> answer;
			if (answer != 'y' && answer != 'n') {
				std::cout << "try again" << std::endl;
			}
			if (answer == 'y') {
				thing->knows = true;
			}
		}
		ask = false;
	}
}

void knows(database* points) {
	rdnode* temp;
	char answer;
	for (int count = 0; count < points->nodes.size(); count++) {
		temp = points->nodes[count];
		if (temp->parents.size() == 0) {
			std::cout << "Do you understand " << temp->topic << " (y/n)?" << std::endl;
			std::cin >> answer;
			if (answer != 'y' && answer != 'n') {
				std::cout << "try again" << std::endl;
				count--;
			}
			if (answer == 'y') {
				temp->knows = true;
				knowsr(temp);
			}
		}
	}
}

void populate(char filename[], database* points) {
	std::vector<std::string> conf;
	std::ifstream inputconf(filename);
	std::string line;
	while (getline (inputconf, line)) {
		conf.push_back(line);
	}
	inputconf.close();
	for (int counter = 0; counter < conf.size(); counter++) {
		line = conf[counter];
		rdnode* tempnode;
		std::string currstring;
		int count = 0;
		std::vector<rdnode*> parenting;
		for(; count < line.size(); count++) {
			if (line[count] != ',' && line[count] != '#') {
				currstring.push_back(line[count]);
			}
			if (line[count] == ',' || line[count] == '#') {
				tempnode = makenode(currstring, points);
				currstring.clear();
				parenting.push_back(tempnode);
			}
			if (line[count] == '#') {
				break;
			}
		}
		count++;
		for (; count < line.size(); count++) {
			currstring.push_back(line[count]);
		}
		tempnode = makenode(currstring, points);
		rdnode* currentparent;
		bool add = true;
		for (count = 0; count < parenting.size(); count++) {
			currentparent = parenting[count];
			for (int counter = 0; counter < tempnode->parents.size(); counter++) {
				if (tempnode->parents[counter] == currentparent) {
					add = false;
				}
			}
			if (add == true) {
				tempnode->parents.push_back(parenting[count]);
				currentparent->children.push_back(tempnode);
			}
		}
	}
}

void printall(database* points) {
	rdnode* temp;
	for (int count = 0; count < points->nodes.size(); count++) {
		temp = points->nodes[count];
		std::cout << temp->topic << std::endl;
	}
}

void rmknows(database* points) {
	rdnode* temp;
	for (int count = 0; count < points->nodes.size(); count++) {
		temp = points->nodes[count];
		temp->knows = false;
	}
}

void student(database* points) {
	std::cout << "Enter name of student file." << std::endl;
	std::vector<std::string> person;
	char filename[30];
	std::cin >> filename;
	std::ifstream inputconf(filename);
	std::string line;
	while (getline (inputconf, line)) {
		person.push_back(line);
	}
	inputconf.close();
	rdnode* tempnode;
	bool finishloop = false;
	for (int count = 0; count < person.size(); count++) {
		for (int counter = 0; counter < points->nodes.size() && finishloop == false; counter++) {
			tempnode = points->nodes[counter];
			if (tempnode->topic == person[count]) {
				tempnode->knows = true;
				finishloop = true;
			}
		}
		finishloop = false;
	}
}

void prerequisites(database* points) {
	std::string topicname;
	std::cin >> topicname;
	rdnode* node;
	bool assigned = false;
	for (int count = 0; count < points->nodes.size() && assigned == false; count++) {
		node = points->nodes[count];
		if (node->topic == topicname) {
			assigned = true;
		}
	}
	if (assigned == false) {
		std::cout << "That topic isn't in the database. You may have spelled or formatted it incorrectly; make sure all your letters are lowercase." << std::endl;
	}
}

int main() {
	char filename[30];
	std::cout << "Enter file name for database." << std::endl;
	std::cin >> filename;
	database* points = new database;
	populate(filename, points);
	//printall(points); //this is useless except for debugging
	bool keeplooping = true;
	std::cout << "Do you have a student file? (y/n)?" << std::endl;
	char answer;
	std::cin >> answer;
	if (answer == 'y') {
		student(points);
	}
	else {
		knows(points);
	}
	while (keeplooping) {
		std::cout << "Your options: Change student (a), List all learnable topics for current student (b), Find out what you need to learn before you can learn a specified topic (c)" << std::endl;
		std::cin >> answer;
		if (answer == 'a') {
			rmknows(points);
			std::cout << "Do you have a student file? (y/n)?" << std::endl;
			char answer;
			std::cin >> answer;
			if (answer == 'y') {
				student(points);
			}
			else {
				knows(points);
			}
		}
		if (answer == 'b') {
			learnable(points);
		}
		if (answer == 'c') {
			prerequisites(points);
		}
	}
	depopulate(points);
	return 0;
}
<commit_msg>Update learning.cpp<commit_after>#include<iostream>
#include<fstream>
#include<string>
#include<vector>
/*to do:
	figure out what other functions might be useful
	populate datastructures.txt more, change name to something better like programming.txt or w/e
*/
struct rdnode {
	public:
	std::string topic;
	std::vector<rdnode*> parents;
	std::vector<rdnode*> children;
	bool knows;
};

struct database {
	std::vector<rdnode*> nodes;
};

void learnable (database* points) {
	rdnode* temp;
	std::vector<rdnode*> learn;
	bool learnability = true;
	for (int count = 0; count < points->nodes.size(); count++) {
		learnability = true;
		temp = points->nodes[count];
		if (temp->knows == false) {
			rdnode* parent;
			for (int counter = 0; counter < temp->parents.size() && learnability == true; counter++) {
				parent = temp->parents[counter];
				if (parent->knows == false) {
					learnability = false;
				}
			}
			if (learnability == true) {
				learn.push_back(temp);
			}
		}
	}
	std::cout << "You can learn: " << learn.size() << " topics." << std::endl;
	for (int count = 0; count < learn.size(); count++) {
		temp = learn[count];
		std::cout << temp->topic << " " << std::endl;
	}
}

void depopulate(database* points) {
	rdnode* delnode;
	for (int count = 0; count < points->nodes.size(); count++) {
		delnode = points->nodes[count];
		delete delnode;
	}
	delete points;
}

rdnode* makenode(std::string topicname, database* points) {
	rdnode* tempnode;
	for (int count = 0; count < points->nodes.size(); count++) {
		tempnode = points->nodes[count];
		if (tempnode->topic == topicname) {
			return tempnode;
		}
	}
	rdnode* newnode = new rdnode;
	newnode->topic = topicname;
	newnode->knows = false;
	points->nodes.push_back(newnode);
	return newnode;
}

void knowsr(rdnode* temp) {
	rdnode* thing;
	bool ask = true;
	for (int count = 0; count < temp->children.size(); count++) {
		thing = temp->children[count];
		rdnode* third;
		for (int counter = 0; count < thing->parents.size(); count++) {
			third = thing->parents[count];
			if (third->knows == false) {
				ask = false;
			}
		}
		if (ask == true) {
			std::cout << "Do you understand " << thing->topic << " (y/n)?" << std::endl;
			char answer;
			std::cin >> answer;
			if (answer != 'y' && answer != 'n') {
				std::cout << "try again" << std::endl;
			}
			if (answer == 'y') {
				thing->knows = true;
			}
		}
		ask = false;
	}
}

void knows(database* points) {
	rdnode* temp;
	char answer;
	for (int count = 0; count < points->nodes.size(); count++) {
		temp = points->nodes[count];
		if (temp->parents.size() == 0) {
			std::cout << "Do you understand " << temp->topic << " (y/n)?" << std::endl;
			std::cin >> answer;
			if (answer != 'y' && answer != 'n') {
				std::cout << "try again" << std::endl;
				count--;
			}
			if (answer == 'y') {
				temp->knows = true;
				knowsr(temp);
			}
		}
	}
}

void populate(char filename[], database* points) {
	std::vector<std::string> conf;
	std::ifstream inputconf(filename);
	std::string line;
	while (getline (inputconf, line)) {
		conf.push_back(line);
	}
	inputconf.close();
	for (int counter = 0; counter < conf.size(); counter++) {
		line = conf[counter];
		rdnode* tempnode;
		std::string currstring;
		int count = 0;
		std::vector<rdnode*> parenting;
		for(; count < line.size(); count++) {
			if (line[count] != ',' && line[count] != '#') {
				currstring.push_back(line[count]);
			}
			if (line[count] == ',' || line[count] == '#') {
				tempnode = makenode(currstring, points);
				currstring.clear();
				parenting.push_back(tempnode);
			}
			if (line[count] == '#') {
				break;
			}
		}
		count++;
		for (; count < line.size(); count++) {
			currstring.push_back(line[count]);
		}
		tempnode = makenode(currstring, points);
		rdnode* currentparent;
		bool add = true;
		for (count = 0; count < parenting.size(); count++) {
			currentparent = parenting[count];
			for (int counter = 0; counter < tempnode->parents.size(); counter++) {
				if (tempnode->parents[counter] == currentparent) {
					add = false;
				}
			}
			if (add == true) {
				tempnode->parents.push_back(parenting[count]);
				currentparent->children.push_back(tempnode);
			}
		}
	}
}

void printall(database* points) {
	rdnode* temp;
	for (int count = 0; count < points->nodes.size(); count++) {
		temp = points->nodes[count];
		std::cout << temp->topic << std::endl;
	}
}

void rmknows(database* points) {
	rdnode* temp;
	for (int count = 0; count < points->nodes.size(); count++) {
		temp = points->nodes[count];
		temp->knows = false;
	}
}

void student(database* points) {
	std::cout << "Enter name of student file." << std::endl;
	std::vector<std::string> person;
	char filename[30];
	std::cin >> filename;
	std::ifstream inputconf(filename);
	std::string line;
	while (getline (inputconf, line)) {
		person.push_back(line);
	}
	inputconf.close();
	rdnode* tempnode;
	bool finishloop = false;
	for (int count = 0; count < person.size(); count++) {
		for (int counter = 0; counter < points->nodes.size() && finishloop == false; counter++) {
			tempnode = points->nodes[counter];
			if (tempnode->topic == person[count]) {
				tempnode->knows = true;
				finishloop = true;
			}
		}
		finishloop = false;
	}
}

std::vector<std::string> prerequisites(rdnode* node, database* points) {
	std::vector<std::string> needtoknow;
	rdnode* parent;
	for (int count = 0; count < node->parents.size(); count++) {
		parent = node->parents[count];
		if (parent->knows == false) {
			needtoknow.push_back(parent->topic);
			std::vector<std::string> alsoneed = prerequisites(parent, points);
			for (int counter = 0; counter < alsoneed.size(); counter++) {
				needtoknow.push_back(alsoneed[counter]);
			}
		}
	}
	return needtoknow;
}

int main() {
	char filename[30];
	std::cout << "Enter file name for database." << std::endl;
	std::cin >> filename;
	database* points = new database;
	populate(filename, points);
	//printall(points); //this is useless except for debugging
	bool keeplooping = true;
	std::cout << "Do you have a student file? (y/n)?" << std::endl;
	char answer;
	std::cin >> answer;
	if (answer == 'y') {
		student(points);
	}
	else {
		knows(points);
	}
	while (keeplooping) {
		std::cout << "Your options: Change student (a), List all learnable topics for current student (b), Find out what you need to learn before you can learn a specified topic (c)" << std::endl;
		std::cin >> answer;
		if (answer == 'a') {
			rmknows(points);
			std::cout << "Do you have a student file? (y/n)?" << std::endl;
			char answer;
			std::cin >> answer;
			if (answer == 'y') {
				student(points);
			}
			else {
				knows(points);
			}
		}
		if (answer == 'b') {
			learnable(points);
		}
		if (answer == 'c') {
			std::string topicname;
			std::cin >> topicname;
			rdnode* node;
			bool assigned = false;
			for (int count = 0; count < points->nodes.size() && assigned == false; count++) {
				node = points->nodes[count];
				if (node->topic == topicname) {
					assigned = true;
				}
			}
			if (assigned == false) {
				std::cout << "That topic isn't in the database. You may have spelled or formatted it incorrectly; make sure all your letters are lowercase." << std::endl;
			}
			else {
				prerequisites(node, points);
			}
		}
	}
	depopulate(points);
	return 0;
}
<|endoftext|>


<commit_before>#include "lirch_plugin.h"
#include "userlist_messages.h"
#include "user_status.h"
#include "received_messages.h"

using namespace std;

class userlist_timer : public message_data
{
public:
	virtual std::unique_ptr<message_data> copy() const {return std::unique_ptr<message_data>(new userlist_timer(*this));}
	static message create(int m) {return message_create("userlist_timer", new userlist_timer(m));}

	userlist_timer(int m) : msecs(m) {}

	int msecs;
};

void run(plugin_pipe p, string name)
{
	p.write(registration_message::create(0, name, "userlist_request"));
	p.write(registration_message::create(0, name, "userlist_timer"));
	p.write(registration_message::create(30000, name, "received"));
	p.write(registration_message::create(30000, name, "received_me"));
	unordered_map<QString, user_status> statuses;
	while (true)
	{
		message m=p.blocking_read();
		if (m.type=="shutdown")
		{
			return;
		}
		else if (m.type=="registration_status")
		{
			auto s=dynamic_cast<registration_status *>(m.getdata());
			if (!s)
				continue;
			if (!s->status)
			{
				if ((0>=s->priority && s->priority>-200) || (30000>=s->priority && s->priority>29000))
					p.write(registration_message::create(s->priority-1, name, s->type));
				else
					return;
			}
			else
			{
				if (s->type=="userlist_timer")
					p.write(userlist_timer::create(10000));
			}
		}
		else if (m.type=="userlist_request")
		{
			p.write(userlist_message::create(statuses));
		}
		else if (m.type=="userlist_timer")
		{
			auto s=dynamic_cast<userlist_timer *>(m.getdata());
			if (!s)
				continue;
			time_t now=time(NULL);
			//Remove all nicks that haven't been seen in 2 minutes
			decltype(statuses.begin()) i;
			while ((i=std::find_if(statuses.begin(), statuses.end(), [now](const std::pair<const QString &, const user_status &> &p) {return p.second.lastseen<now-2*60;}))!=statuses.end())
				statuses.erase(i);
			p.write(userlist_message::create(statuses));
			p.write(userlist_timer::create(s->msecs));
		}
		else if (m.type=="received")
		{
			auto s=dynamic_cast<received_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			statuses[s->nick].nick=s->nick;
			statuses[s->nick].channels.insert(s->channel);
			statuses[s->nick].ip=s->ipAddress;
			statuses[s->nick].lastseen=time(NULL);
		}
		else if (m.type=="received_me")
		{
			auto s=dynamic_cast<received_me_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			statuses[s->nick].nick=s->nick;
			statuses[s->nick].channels.insert(s->channel);
			statuses[s->nick].ip=s->ipAddress;
			statuses[s->nick].lastseen=time(NULL);
		}
		else
			p.write(m.decrement_priority());
	}
}
<commit_msg>Fixed a potential crash bug<commit_after>#include <thread>

#include "lirch_plugin.h"
#include "userlist_messages.h"
#include "user_status.h"
#include "received_messages.h"

using namespace std;

class userlist_timer : public message_data
{
public:
	virtual std::unique_ptr<message_data> copy() const {return std::unique_ptr<message_data>(new userlist_timer(*this));}
	static message create(int m) {return message_create("userlist_timer", new userlist_timer(m));}

	userlist_timer(int m) : msecs(m) {}

	int msecs;
};

void run(plugin_pipe p, string name)
{
	p.write(registration_message::create(0, name, "userlist_request"));
	p.write(registration_message::create(0, name, "userlist_timer"));
	p.write(registration_message::create(30000, name, "received"));
	p.write(registration_message::create(30000, name, "received_me"));
	unordered_map<QString, user_status> statuses;
	while (true)
	{
		message m=p.blocking_read();
		if (m.type=="shutdown")
		{
			return;
		}
		else if (m.type=="registration_status")
		{
			auto s=dynamic_cast<registration_status *>(m.getdata());
			if (!s)
				continue;
			if (!s->status)
			{
				if ((0>=s->priority && s->priority>-200) || (30000>=s->priority && s->priority>29000))
					p.write(registration_message::create(s->priority-1, name, s->type));
				else
					return;
			}
			else
			{
				if (s->type=="userlist_timer")
					p.write(userlist_timer::create(10000));
			}
		}
		else if (m.type=="userlist_request")
		{
			p.write(userlist_message::create(statuses));
		}
		else if (m.type=="userlist_timer")
		{
			auto s=dynamic_cast<userlist_timer *>(m.getdata());
			if (!s)
				continue;
			time_t now=time(NULL);
			//Remove all nicks that haven't been seen in 2 minutes
			decltype(statuses.begin()) i;
			while ((i=std::find_if(statuses.begin(), statuses.end(), [now](const std::pair<const QString &, const user_status &> &p) {return p.second.lastseen<now-2*60;}))!=statuses.end())
				statuses.erase(i);
			p.write(userlist_message::create(statuses));
			int msecs=s->msecs;
			thread th([&p,msecs]()
			{
				plugin_pipe pp;
				this_thread::sleep_for(chrono::milliseconds(msecs));
				pp.write(userlist_timer::create(msecs));
			});
			th.detach();
		}
		else if (m.type=="received")
		{
			auto s=dynamic_cast<received_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			statuses[s->nick].nick=s->nick;
			statuses[s->nick].channels.insert(s->channel);
			statuses[s->nick].ip=s->ipAddress;
			statuses[s->nick].lastseen=time(NULL);
		}
		else if (m.type=="received_me")
		{
			auto s=dynamic_cast<received_me_message *>(m.getdata());
			if (!s)
				continue;
			p.write(m.decrement_priority());
			statuses[s->nick].nick=s->nick;
			statuses[s->nick].channels.insert(s->channel);
			statuses[s->nick].ip=s->ipAddress;
			statuses[s->nick].lastseen=time(NULL);
		}
		else
			p.write(m.decrement_priority());
	}
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/inbound_path.hpp"

#include "caf/send.hpp"
#include "caf/logger.hpp"
#include "caf/no_stages.hpp"
#include "caf/local_actor.hpp"

namespace caf {

inbound_path::stats_t::stats_t() : ring_iter(0) {
  measurement x{0, timespan{0}};
  measurements.resize(stats_sampling_size, x);
}

auto inbound_path::stats_t::calculate(timespan c, timespan d)
  -> calculation_result {
  // Max throughput = C * (N / t), where C = cycle length, N = measured items,
  // and t = measured time. Desired batch size is the same formula with D
  // instead of C.
  long total_ns = 0;
  long total_items = 0;
  for (auto& x : measurements) {
    total_ns += static_cast<long>(x.calculation_time.count());
    total_items += x.batch_size;
  }
  if (total_ns == 0)
    return {1, 1};
  // Instead of C * (N / t) we calculate N * (C / t) to avoid imprecisions due
  // to double rounding for very small numbers.
  auto ct = static_cast<double>(c.count()) / total_ns;
  auto dt = static_cast<double>(d.count()) / total_ns;
  return {std::max(static_cast<long>(total_items * ct), 1l),
          std::max(static_cast<long>(total_items * dt), 1l)};
}

void inbound_path::stats_t::store(measurement x) {
  measurements[ring_iter] = x;
  ring_iter = (ring_iter + 1) % stats_sampling_size;
}

inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id,
                           strong_actor_ptr ptr)
    : mgr(std::move(mgr_ptr)),
      hdl(std::move(ptr)),
      slots(id),
      assigned_credit(0),
      prio(stream_priority::normal),
      last_acked_batch_id(0),
      last_batch_id(0) {
  mgr->register_input_path(this);
}

inbound_path::~inbound_path() {
  mgr->deregister_input_path(this);
}

void inbound_path::handle(downstream_msg::batch& x) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(x));
  auto batch_size = x.xs_size;
  assigned_credit -= batch_size;
  last_batch_id = x.id;
  auto& clock = mgr->self()->clock();
  auto t0 = clock.now();
  mgr->handle(this, x);
  auto t1 = clock.now();
  auto dt = clock.difference(atom("batch"), batch_size, t0, t1);
  stats.store({batch_size, dt});
  mgr->push();
}

void inbound_path::emit_ack_open(local_actor* self, actor_addr rebind_from) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(rebind_from));
  assigned_credit = 50; // TODO: put constant in some header
  int32_t desired_batch_size = 50; // TODO: put constant in some header
  unsafe_send_as(self, hdl,
                 make<upstream_msg::ack_open>(
                   slots.invert(), self->address(), std::move(rebind_from),
                   self->ctrl(), static_cast<int32_t>(assigned_credit),
                   desired_batch_size));
}

void inbound_path::emit_ack_batch(local_actor* self, long queued_items,
                                  timespan cycle, timespan complexity) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(queued_items) << CAF_ARG(cycle)
                << CAF_ARG(complexity));
  if (last_acked_batch_id == last_batch_id)
    return;
  auto x = stats.calculate(cycle, complexity);
  // Hand out enough credit to fill our queue for 2 cycles.
  auto credit = std::max((x.max_throughput * 2)
                         - (assigned_credit - queued_items),
                         0l);
  auto batch_size = static_cast<int32_t>(x.items_per_batch);
  if (credit != 0)
    assigned_credit += credit;
  CAF_LOG_DEBUG(CAF_ARG(credit) << CAF_ARG(batch_size));
  unsafe_send_as(self, hdl,
                 make<upstream_msg::ack_batch>(slots.invert(), self->address(),
                                               static_cast<int32_t>(credit),
                                               batch_size, last_batch_id));
  last_acked_batch_id = last_batch_id;
}

void inbound_path::emit_regular_shutdown(local_actor* self) {
  CAF_LOG_TRACE(CAF_ARG(slots));
  unsafe_send_as(self, hdl, make<upstream_msg::drop>(slots, self->address()));
}

void inbound_path::emit_irregular_shutdown(local_actor* self, error reason) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(reason));
  unsafe_send_as(self, hdl,
                 make<upstream_msg::forced_drop>(
                   slots.invert(), self->address(), std::move(reason)));
}

void inbound_path::emit_irregular_shutdown(local_actor* self,
                                           stream_slots slots,
                                           const strong_actor_ptr& hdl,
                                           error reason) {
  unsafe_send_as(self, hdl,
                 make<upstream_msg::forced_drop>(
                   slots.invert(), self->address(), std::move(reason)));
}

} // namespace caf
<commit_msg>Replace magic numbers with constants<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/inbound_path.hpp"

#include "caf/send.hpp"
#include "caf/logger.hpp"
#include "caf/no_stages.hpp"
#include "caf/local_actor.hpp"

namespace caf {

inbound_path::stats_t::stats_t() : ring_iter(0) {
  measurement x{0, timespan{0}};
  measurements.resize(stats_sampling_size, x);
}

auto inbound_path::stats_t::calculate(timespan c, timespan d)
  -> calculation_result {
  // Max throughput = C * (N / t), where C = cycle length, N = measured items,
  // and t = measured time. Desired batch size is the same formula with D
  // instead of C.
  long total_ns = 0;
  long total_items = 0;
  for (auto& x : measurements) {
    total_ns += static_cast<long>(x.calculation_time.count());
    total_items += x.batch_size;
  }
  if (total_ns == 0)
    return {1, 1};
  // Instead of C * (N / t) we calculate N * (C / t) to avoid imprecisions due
  // to double rounding for very small numbers.
  auto ct = static_cast<double>(c.count()) / total_ns;
  auto dt = static_cast<double>(d.count()) / total_ns;
  return {std::max(static_cast<long>(total_items * ct), 1l),
          std::max(static_cast<long>(total_items * dt), 1l)};
}

void inbound_path::stats_t::store(measurement x) {
  measurements[ring_iter] = x;
  ring_iter = (ring_iter + 1) % stats_sampling_size;
}

inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id,
                           strong_actor_ptr ptr)
    : mgr(std::move(mgr_ptr)),
      hdl(std::move(ptr)),
      slots(id),
      assigned_credit(0),
      prio(stream_priority::normal),
      last_acked_batch_id(0),
      last_batch_id(0) {
  mgr->register_input_path(this);
}

inbound_path::~inbound_path() {
  mgr->deregister_input_path(this);
}

void inbound_path::handle(downstream_msg::batch& x) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(x));
  auto batch_size = x.xs_size;
  assigned_credit -= batch_size;
  last_batch_id = x.id;
  auto& clock = mgr->self()->clock();
  auto t0 = clock.now();
  mgr->handle(this, x);
  auto t1 = clock.now();
  auto dt = clock.difference(atom("batch"), batch_size, t0, t1);
  stats.store({batch_size, dt});
  mgr->push();
}

void inbound_path::emit_ack_open(local_actor* self, actor_addr rebind_from) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(rebind_from));
  assigned_credit = initial_credit;
  int32_t desired_batch_size = initial_credit;
  unsafe_send_as(self, hdl,
                 make<upstream_msg::ack_open>(
                   slots.invert(), self->address(), std::move(rebind_from),
                   self->ctrl(), static_cast<int32_t>(assigned_credit),
                   desired_batch_size));
}

void inbound_path::emit_ack_batch(local_actor* self, long queued_items,
                                  timespan cycle, timespan complexity) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(queued_items) << CAF_ARG(cycle)
                << CAF_ARG(complexity));
  if (last_acked_batch_id == last_batch_id)
    return;
  auto x = stats.calculate(cycle, complexity);
  // Hand out enough credit to fill our queue for 2 cycles.
  auto credit = std::max((x.max_throughput * 2)
                         - (assigned_credit - queued_items),
                         0l);
  auto batch_size = static_cast<int32_t>(x.items_per_batch);
  if (credit != 0)
    assigned_credit += credit;
  CAF_LOG_DEBUG(CAF_ARG(credit) << CAF_ARG(batch_size));
  unsafe_send_as(self, hdl,
                 make<upstream_msg::ack_batch>(slots.invert(), self->address(),
                                               static_cast<int32_t>(credit),
                                               batch_size, last_batch_id));
  last_acked_batch_id = last_batch_id;
}

void inbound_path::emit_regular_shutdown(local_actor* self) {
  CAF_LOG_TRACE(CAF_ARG(slots));
  unsafe_send_as(self, hdl, make<upstream_msg::drop>(slots, self->address()));
}

void inbound_path::emit_irregular_shutdown(local_actor* self, error reason) {
  CAF_LOG_TRACE(CAF_ARG(slots) << CAF_ARG(reason));
  unsafe_send_as(self, hdl,
                 make<upstream_msg::forced_drop>(
                   slots.invert(), self->address(), std::move(reason)));
}

void inbound_path::emit_irregular_shutdown(local_actor* self,
                                           stream_slots slots,
                                           const strong_actor_ptr& hdl,
                                           error reason) {
  unsafe_send_as(self, hdl,
                 make<upstream_msg::forced_drop>(
                   slots.invert(), self->address(), std::move(reason)));
}

} // namespace caf
<|endoftext|>