Файл: Локальная база данных.docx

ВУЗ: Не указан

Категория: Реферат

Дисциплина: Не указана

Добавлен: 17.03.2024

Просмотров: 11

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


Министерство образования, науки и молодежной политики Забайкальского края
Государственное профессиональное образовательное учреждение
«ЧИТИНСКИЙ ТЕХНИКУМ ОТРАСЛЕВЫХ ТЕХНОЛОГИЙ И БИЗНЕСА» (ГПОУ «ЧТОТиБ»)

Курсовое проектирование по теме «Объектно-ориентированное программирование»

МДК 01.02 раздела «Прикладное программирование»

ПМ1 «Разработка программных модулей программного обеспечения для компьютерных систем»
«Локальная база данных»

Выполнил
_____________Т.Н. Устинов
студент группы ПКС-14-1
«___»__________2017 г.

Руководитель работы
_____________Т.М. Смирнова
«___»__________2017 г.

2017 г.

Содержание



1.

Введение
Цель и задачи курсового проектирования

Данный проект был разработан исключительно в учебных целях, при его создании не преследовались не какие другие цели. Потому что этот проект является локальной базой данных, аналогово которой большое множество которые удобнее и более функциональные.

Цель выполнения данного курсового проекта была в том, чтобы закрепить понятие концепции объектно-ориентированного программирования, изучить как устроены высокоуровневые визуальные системы разработки программ, и затронуть разработку программы с примитивным графическим интерфейсом.

Тема проекта «Локальная база данных Сотрудники» была выбрана потому что как пример она хорошо подходит, но не более. У этой программы простые типы хранимых данных, и можно реализовать много функций обработки этой базы.

Теоретическая часть
Данная база хранит сотрудников, рабочих и в принципе может хранить что угодно, с информацией о каждом сотруднике.

Хранит информацию:

  1. Имя

  2. Фамилия

  3. Количество лет

  4. Оклад

  5. Фото (точнее путь на фото)

Реализованы функции:

  1. Вывод сотрудников

  2. Добавление новых сотрудников

  3. Сохранение базы в бинарный файл

  4. Поиск

  5. Редактирование

  6. Удаление

  7. Сортировка

  8. И вывод графика по зарплате


Для организации структуры в оперативной памяти использовался связный список. Связный список — это базовая динамическая структура данных в информатике, состоящая из узлов, каждый из которых содержит как собственно данные, так и одну или две ссылки («связки») на следующий и/или предыдущий узел списка. Принципиальным преимуществом перед массивом является структурная гибкость: порядок элементов связного списка может не совпадать с порядком расположения элементов данных в памяти компьютера, а порядок обхода списка всегда явно задаётся его внутренними связями. И собственные данные в узле являются переменная типа string которая хранит имя, фамилию и путь до файла, переменная типа int которая хранит возраст, и id текущего узла, и переменная типа double значение которой является оклад. Были реализованы статические переменные типа int в которых хранятся количество всех узлов, минимальная и максимальная зарплата соответственно.

Для сортировки этой структуры было использовано «Бинарное дерево». Бинарное дерево — это двоичное дерево, для которого выполняются дополнительные условия при построении дерева (рис. 1).

Двоичное дерево — иерархическая структура данных, в которой каждый узел имеет не более двух потомков (детей). Как правило, первый называется родительским узлом, а дети называются левым и правым наследниками.
рис. 1: пример Бинарного дерева

Для сохранения базы использовалась запись в бинарный файл. Запись в бинарный файл объекта похожа на его отображение: берутся данные из оперативной памяти и пишутся как есть. Считывание происходит аналогичным образом, файл считывается и записывается в память так как он записан в файл.

Для поиска была написана функция которая позволяет использовать маски: * - для экранирования сколько угодного количества букв, и ? для одного неизвестного символа. Для не строковых полей используется жёсткий поиск, если значение задано, то результаты, которые не равны этому не строковому значению будут отброшены.

Для удобного использования редактирования был изменен класс библиотеки GRAPHICS, для того чтобы в объект класса In_box можно было выставить значение динамически.

Так же для возможности динамического изменения изображения пришлось поменять тип доступа к переменной p из класса Image с приватной на публичную.

Для реализации сортировки было использовано Бинарное дерево, перед началом сортировки мы выбираем поле, по которому сортировать, и дальше выстраивается бинарное дерево, в дальнейшем отсортированный список можно сохранить. Для этого полностью удаляется старый список и создается новый значения которого берутся из уже отсортированного бинарного дерева.

График отображает зарплату сотрудников (зарплата заносится в т.р) где минимальная зарплата 0 и максимальная 1000м.

Практическая часть
Emploer.h

class Employer_class

{

public:

static int number;

static Employer_class* First;

static Employer_class* Last;

Employer_class* Next;

Employer_class* Previous;

string family;

string name;

int age;

double salary;

string photo;

static double salary_max;

static double salary_min;

int i;

Employer_class(string f = " ", string n = " ", int a= 0, double s = 0.0, string i = "") :family(f), name(n),age(a), salary(s),photo(i) {}

static void add(Employer_class* obj)

{

if (obj->salary > salary_max) salary_max = obj->salary;

if (obj->salary < salary_min) salary_min = obj->salary;

if (Last == NULL)

{

salary_min = obj->salary;

First = obj;

obj->Previous = NULL;

}

else

{

obj->Previous = Last;

Last->Next = obj;

}

Last = obj;

obj->Next = NULL;

obj->i = number;

number++;

}

static bool empty()

{

if (number == 0) return true;

else return false;

}

static void del(Employer_class* obj)

{

Employer_class* temp = obj->Next;

while (temp)

{

temp->i--;

temp = temp->Next;

}

if (First == Last)

{

First = NULL;

Last = NULL;

}

else if (obj == First)

{

First = First->Next;

First->Previous = NULL;

}

else if (obj == Last)

{

Last = Last->Previous;

Last->Next = NULL;

}

else

{

obj->Previous->Next = obj->Next;

obj->Next->Previous = obj->Previous;
}

obj = NULL;

delete obj;

number--;

}

};

class Binary_Tree

{

public:

string family;

string name;

int age;

double salary;

string photo;

Binary_Tree* Left;

Binary_Tree* Right;

static Binary_Tree* Tree;

Binary_Tree(string f = " ", string n = " ", int a= 0, double s = 0.0) :family(f), name(n),age(a), salary(s) {}

static void create_tree(Employer_class* obj, Binary_Tree*& Tree, int pole)

{

if (Tree == NULL)

{

Tree = new Binary_Tree();

Tree->name = obj->name;

Tree->family = obj->family;

Tree->age = obj->age;

Tree->salary = obj->salary;

Tree->photo = obj->photo;

Tree->Left = NULL;

Tree->Right = NULL;

}

else

switch (pole) {

case 0:

if (Tree->name > obj->name) create_tree(obj, Tree->Left, pole);

else create_tree(obj, Tree->Right, pole);

break;

case 1:

if (Tree->family > obj->family) create_tree(obj, Tree->Left, pole);

else create_tree(obj, Tree->Right, pole);

break;

case 2:

if (Tree->age > obj->age) create_tree(obj, Tree->Left, pole);

else create_tree(obj, Tree->Right, pole);

break;

case 3:

if (Tree->salary > obj->salary) create_tree(obj, Tree->Left, pole);

else create_tree(obj, Tree->Right, pole);

break;

default:

break;

}

}

static void print_tree(Binary_Tree* Tree, vector &mass)

{

if (Tree)

{

print_tree(Tree->Left, mass);

mass.push_back(Tree);

print_tree(Tree->Right, mass);

}

}

static void del_tree(Binary_Tree*& Tree)

{

if (Tree)

{

del_tree(Tree->Left);

del_tree(Tree->Right);

delete Tree;

Tree = NULL;

}

}

};

class Scale

{

int cbase;

int vbase;

double scale;

public:

Scale(int cb, int vb, double s):cbase(cb),vbase(vb),scale(s){}

int operator () (int v) const

{

return cbase+(v-vbase)*scale;

}

};

Graph.h
//

// This is a GUI support code to the chapters 12-16 of the book

// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup

//
#ifndef GRAPH_GUARD

#define GRAPH_GUARD 1
#include

#include

#include "Point.h"

#include "std_lib_facilities.h"
namespace Graph_lib {
// defense against ill-behaved Linux macros:

#undef major

#undef minor
//------------------------------------------------------------------------------
// Color is the type we use to represent color. We can use Color like this:

// grid.set_color(Color::red);

struct Color {

enum Color_type {

red=FL_RED,

blue=FL_BLUE,

green=FL_GREEN,

yellow=FL_YELLOW,

white=FL_WHITE,

black=FL_BLACK,

magenta=FL_MAGENTA,

cyan=FL_CYAN,

dark_red=FL_DARK_RED,

dark_green=FL_DARK_GREEN,

dark_yellow=FL_DARK_YELLOW,

dark_blue=FL_DARK_BLUE,

dark_magenta=FL_DARK_MAGENTA,

dark_cyan=FL_DARK_CYAN

};
enum Transparency { invisible = 0, visible=255 };
Color(Color_type cc) :c(Fl_Color(cc)), v(visible) { }

Color(Color_type cc, Transparency vv) :c(Fl_Color(cc)), v(vv) { }

Color(int cc) :c(Fl_Color(cc)), v(visible) { }

Color(Transparency vv) :c(Fl_Color()), v(vv) { } // default color
int as_int() const { return c; }
char visibility() const { return v; }

void set_visibility(Transparency vv) { v=vv; }

private:

char v; // invisible and visible for now

Fl_Color c;

};
//------------------------------------------------------------------------------
struct Line_style {

enum Line_style_type {

solid=FL_SOLID, // -------

dash=FL_DASH, // - - - -

dot=FL_DOT, // .......

dashdot=FL_DASHDOT, // - . - .

dashdotdot=FL_DASHDOTDOT, // -..-..

};
Line_style(Line_style_type ss) :s(ss), w(0) { }

Line_style(Line_style_type lst, int ww) :s(lst), w(ww) { }

Line_style(int ss) :s(ss), w(0) { }
int width() const { return w; }

int style() const { return s; }

private:

int s;

int w;

};
//------------------------------------------------------------------------------
class Font {

public:

enum Font_type {

helvetica=FL_HELVETICA,

helvetica_bold=FL_HELVETICA_BOLD,

helvetica_italic=FL_HELVETICA_ITALIC,

helvetica_bold_italic=FL_HELVETICA_BOLD_ITALIC,

courier=FL_COURIER,

courier_bold=FL_COURIER_BOLD,

courier_italic=FL_COURIER_ITALIC,

courier_bold_italic=FL_COURIER_BOLD_ITALIC,

times=FL_TIMES,

times_bold=FL_TIMES_BOLD,

times_italic=FL_TIMES_ITALIC,

times_bold_italic=FL_TIMES_BOLD_ITALIC,

symbol=FL_SYMBOL,

screen=FL_SCREEN,

screen_bold=FL_SCREEN_BOLD,

zapf_dingbats=FL_ZAPF_DINGBATS

};
Font(Font_type ff) :f(ff) { }

Font(int ff) :f(ff) { }
int as_int() const { return f; }

private:

int f;

};
//------------------------------------------------------------------------------
template class Vector_ref {

vector v;

vector owned;

public:

Vector_ref() {}

Vector_ref(T& a) { push_back(a); }

Vector_ref(T& a, T& b);

Vector_ref(T& a, T& b, T& c);

Vector_ref(T* a, T* b = 0, T* c = 0, T* d = 0)

{

if (a) push_back(a);

if (b) push_back(b);

if (c) push_back(c);

if (d) push_back(d);

}
Vector_ref() { for (int i=0; ivoid push_back(T& s) { v.push_back(&s); }

void push_back(T* p) { v.push_back(p); owned.push_back(p); }
T& operator[](int i) { return *v[i]; }

const T& operator[](int i) const { return *v[i]; }
int size() const { return v.size(); }
private: // prevent copying

Vector_ref(const Vector&);

Vector_ref& operator=(const Vector&);

};
//------------------------------------------------------------------------------
typedef double Fct(double);
class Shape { // deals with color and style, and holds sequence of lines

public:

void draw() const; // deal with color and draw lines

virtual void move(int dx, int dy); // move the shape +=dx and +=dy
void set_color(Color col) { lcolor = col; }

Color color() const { return lcolor; }

void set_style(Line_style sty) { ls = sty; }

Line_style style() const { return ls; }

void set_fill_color(Color col) { fcolor = col; }

Color fill_color() const { return fcolor; }
Point point(int i) const { return points[i]; } // read only access to points

int number_of_points() const { return int(points.size()); }
virtual
Shape() { }

protected:

Shape();

virtual void draw_lines() const; // draw the appropriate lines

void add(Point p); // add p to points

void set_point(int i,Point p); // points[i]=p;

private:

vector points; // not used by all shapes

Color lcolor; // color for lines and characters

Line_style ls;

Color fcolor; // fill color
Shape(const Shape&); // prevent copying

Shape& operator=(const Shape&);

};
//------------------------------------------------------------------------------
struct Function : Shape {

// the function parameters are not stored

Function(Fct f, double r1, double r2, Point orig,

int count = 100, double xscale = 25, double yscale = 25);

};
//------------------------------------------------------------------------------
struct Line : Shape { // a Line is a Shape defined by two Points

Line(Point p1, Point p2); // construct a line from two points

};
//------------------------------------------------------------------------------
struct Rectangle : Shape {
Rectangle(Point xy, int ww, int hh) : w(ww), h(hh)

{

add(xy);

if (h<=0 || w<=0) error("Bad rectangle: non-positive side");

}
Rectangle(Point x, Point y) : w(y.x-x.x), h(y.y-x.y)

{

add(x);

if (h<=0 || w<=0) error("Bad rectangle: non-positive width or height");

}

void draw_lines() const;
int height() const { return h; }

int width() const { return w; }

private:

int h; // height

int w; // width

};
//------------------------------------------------------------------------------
struct Open_polyline : Shape { // open sequence of lines

void add(Point p) { Shape::add(p); }

void draw_lines() const;

};
//------------------------------------------------------------------------------
struct Closed_polyline : Open_polyline { // closed sequence of lines

void draw_lines() const;

};
//------------------------------------------------------------------------------
struct Polygon : Closed_polyline { // closed sequence of non-intersecting lines

void add(Point p);

void draw_lines() const;

};
//------------------------------------------------------------------------------
struct Lines : Shape { // related lines

void draw_lines() const;

void add(Point p1, Point p2); // add a line defined by two points

};
//------------------------------------------------------------------------------
struct Text : Shape {

// the point is the bottom left of the first letter

Text(Point x, const string& s) : lab(s), fnt(fl_font()), fnt_sz(fl_size()) { add(x); }
void draw_lines() const;
void set_label(const string& s) { lab = s; }

string label() const { return lab; }
void set_font(Font f) { fnt = f; }

Font font() const { return Font(fnt); }
void set_font_size(int s) { fnt_sz = s; }

int font_size() const { return fnt_sz; }

private:

string lab; // label

Font fnt;

int fnt_sz;

};
//------------------------------------------------------------------------------
struct Axis : Shape {

enum Orientation { x, y, z };

Axis(Orientation d, Point xy, int length,

int number_of_notches=0, string label = "");
void draw_lines() const;

void move(int dx, int dy);

void set_color(Color c);
Text label;

Lines notches;

};
//------------------------------------------------------------------------------

struct Circle : Shape {

Circle(Point p, int rr) // center and radius

:r(rr) { add(Point(p.x-r,p.y-r)); }
void draw_lines() const;
Point center() const;
void set_radius(int rr) { set_point(0,Point(center().x-rr,center().y-rr)); r=rr; }

int radius() const { return r; }

private:

int r;

};
//------------------------------------------------------------------------------
struct Ellipse : Shape {

Ellipse(Point p, int ww, int hh) // center, min, and max distance from center

:w(ww), h(hh) { add(Point(p.x-ww,p.y-hh)); }
void draw_lines() const;
Point center() const { return Point(point(0).x+w,point(0).y+h); }

Point focus1() const {

if (h<=w)// foci are on the x-axis:

return Point(center().x+int(sqrt(double(w*w-h*h))),center().y);

else // foci are on the y-axis:

return Point(center().x,center().y+int(sqrt(double(h*h-w*w))));

}
Point focus2() const {

if (h<=w)

return Point(center().x-int(sqrt(double(w*w-h*h))),center().y);

else

return Point(center().x,center().y-int(sqrt(double(h*h-w*w))));

}

//Point focus2() const { return Point(center().x-int(sqrt(double(abs(w*w-h*h)))),center().y); }

void set_major(int ww) { set_point(0,Point(center().x-ww,center().y-h)); w=ww; }

int major() const { return w; }

void set_minor(int hh) { set_point(0,Point(center().x-w,center().y-hh)); h=hh; }

int minor() const { return h; }

private:

int w;

int h;

};
//------------------------------------------------------------------------------
struct Marked_polyline : Open_polyline {

Marked_polyline(const string& m) :mark(m) { }

void draw_lines() const;

private:

string mark;

};
//------------------------------------------------------------------------------
struct Marks : Marked_polyline {

Marks(const string& m) :Marked_polyline(m)

{

set_color(Color(Color::invisible));

}

};
//------------------------------------------------------------------------------
struct Mark : Marks {

Mark(Point xy, char c) : Marks(string(1,c))

{

add(xy);

}

};
//------------------------------------------------------------------------------
struct Suffix {

enum Encoding { none, jpg, gif };

};
Suffix::Encoding get_encoding(const string& s);
//------------------------------------------------------------------------------
struct Image : Shape {

Image(Point xy, string file_name, Suffix::Encoding e = Suffix::none);

Image() { delete p; }


void draw_lines() const;

void set_mask(Point xy, int ww, int hh) { w=ww; h=hh; cx=xy.x; cy=xy.y; }

Fl_Image* p;

private:

int w,h; // define "masking box" within image relative to position (cx,cy)

int cx,cy;

Text fn;

};
//------------------------------------------------------------------------------
struct Bad_image : Fl_Image {

Bad_image(int h, int w) : Fl_Image(h,w,0) { }

void draw(int x,int y, int, int, int, int) { draw_empty(x,y); }

};
//------------------------------------------------------------------------------
} // of namespace Graph_lib
#endif


GUI.h
//

// This is a GUI support code to the chapters 12-16 of the book

// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup

//
#ifndef GUI_GUARD

#define GUI_GUARD
#include "Window.h"

#include "Graph.h"

namespace Graph_lib {

#include
//------------------------------------------------------------------------------
typedef void* Address; // Address is a synonym for void*

typedef void(*Callback)(Address, Address); // FLTK's required function type for all callbacks
//------------------------------------------------------------------------------
template W& reference_to(Address pw)

// treat an address as a reference to a W

{

return *static_cast(pw);

}
//------------------------------------------------------------------------------
class Widget {

// Widget is a handle to an Fl_widget - it is *not* an Fl_widget

// We try to keep our interface classes at arm's length from FLTK

public:

Widget(Point xy, int w, int h, const string& s, Callback cb)

: loc(xy), width(w), height(h), label(s), do_it(cb)

{}
virtual void move(int dx,int dy) { hide(); pw->position(loc.x+=dx, loc.y+=dy); show(); }

virtual void hide() { pw->hide(); }

virtual void show() { pw->show(); }

virtual void attach(Window&) = 0;
Point loc;

int width;

int height;

string label;

Callback do_it;
virtual

Widget() { }
protected:

Window* own; // every Widget belongs to a Window

Fl_Widget* pw; // connection to the FLTK Widget

private:

Widget& operator=(const Widget&); // don't copy Widgets

Widget(const Widget&);

};
//------------------------------------------------------------------------------
struct Button : Widget {

Button(Point xy, int w, int h, const string& label, Callback cb)

: Widget(xy,w,h,label,cb)

{}
void attach(Window&);

};
//------------------------------------------------------------------------------
struct In_box : Widget {

In_box(Point xy, int w, int h, const string& s)

:Widget(xy,w,h,s,0) { }

int get_int();

string get_string();

void put(const string&);

void attach(Window& win);

};
//------------------------------------------------------------------------------
struct Out_box : Widget {

Out_box(Point xy, int w, int h, const string& s)

:Widget(xy,w,h,s,0) { }

void put(int);

void put(const string&);

void attach(Window& win);

};
//------------------------------------------------------------------------------
struct Menu : Widget {

enum Kind { horizontal, vertical };

Menu(Point xy, int w, int h, Kind kk, const string& label)

: Widget(xy,w,h,label,0), k(kk), offset(0)

{}
Vector_ref Window() { }

int x_max() const { return w; }

int y_max() const { return h; }
void resize(int ww, int hh) { w=ww, h=hh; size(ww,hh); }
void set_label(const string& s) { copy_label(s.c_str()); }
void attach(Shape& s) { shapes.push_back(&s); }

void attach(Widget&);
void detach(Shape& s); // remove s from shapes

void detach(Widget& w); // remove w from window (deactivates callbacks)
void put_on_top(Shape& p); // put p on top of other shapes
protected:

void draw();
private:

vector shapes; // shapes attached to window

int w,h; // window size
void init();

};
//------------------------------------------------------------------------------
int gui_main(); // invoke GUI library's main event loop

inline int x_max() { return Fl::w(); } // width of screen in pixels

inline int y_max() { return Fl::h(); } // height of screen in pixels
} // of namespace Graph_lib
#endif // WINDOW_GUARD
gr1.cpp

#include "Simple_window.h"

#include "Graph.h"

#include "GUI.h"

#include "Emploer.h"

using namespace Graph_lib;

Employer_class* Employer_class::First = NULL;

Employer_class* Employer_class::Last = NULL;

double Employer_class::salary_max = 0;

double Employer_class::salary_min = 0;

int Employer_class::number = 0;

Binary_Tree* Binary_Tree::Tree = NULL;

int main()

{

Employer win(Point(100,100),1200,600,"Сотрудники");

return gui_main();

}

Graph.cpp
//

// This is a GUI support code to the chapters 12-16 of the book

// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup

//
#include

#include

#include "Graph.h"
//------------------------------------------------------------------------------
namespace Graph_lib {
//------------------------------------------------------------------------------
Shape::Shape() :

lcolor(fl_color()), // default color for lines and characters

ls(0), // default style

fcolor(Color::invisible) // no fill

{}
//------------------------------------------------------------------------------
void Shape::add(Point p) // protected

{

points.push_back(p);

}
//------------------------------------------------------------------------------
void Shape::set_point(int i,Point p) // not used; not necessary so far

{

points[i] = p;

}
//------------------------------------------------------------------------------
void Shape::draw_lines() const

{

if (color().visibility() && 1
for (unsigned int i=1; i
fl_line(points[i-1].x,points[i-1].y,points[i].x,points[i].y);

}
//------------------------------------------------------------------------------
void Shape::draw() const

{

Fl_Color oldc = fl_color();

// there is no good portable way of retrieving the current style

fl_color(lcolor.as_int()); // set color

fl_line_style(ls.style(),ls.width()); // set style

draw_lines();

fl_color(oldc); // reset color (to previous)

fl_line_style(0); // reset line style to default

}
//------------------------------------------------------------------------------

void Shape::move(int dx, int dy) // move the shape +=dx and +=dy

{

for (int i = 0; i
points[i].x+=dx;

points[i].y+=dy;

}

}
//------------------------------------------------------------------------------
Line::Line(Point p1, Point p2) // construct a line from two points

{

add(p1); // add p1 to this shape

add(p2); // add p2 to this shape

}
//------------------------------------------------------------------------------
void Lines::add(Point p1, Point p2)

{

Shape::add(p1);

Shape::add(p2);

}
//------------------------------------------------------------------------------
// draw lines connecting pairs of points

void Lines::draw_lines() const

{

if (color().visibility())

for (int i=1; i
fl_line(point(i-1).x,point(i-1).y,point(i).x,point(i).y);

}
//------------------------------------------------------------------------------
// does two lines (p1,p2) and (p3,p4) intersect?

// if se return the distance of the intersect point as distances from p1

inline pair line_intersect(Point p1, Point p2, Point p3, Point p4, bool& parallel)

{

double x1 = p1.x;

double x2 = p2.x;

double x3 = p3.x;

double x4 = p4.x;

double y1 = p1.y;

double y2 = p2.y;

double y3 = p3.y;

double y4 = p4.y;
double denom = ((y4 - y3)*(x2-x1) - (x4-x3)*(y2-y1));

if (denom == 0){

parallel= true;

return pair(0,0);

}

parallel = false;

return pair( ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3))/denom,

((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3))/denom);

}
//------------------------------------------------------------------------------
//intersection between two line segments

//Returns true if the two segments intersect,

//in which case intersection is set to the point of intersection

bool line_segment_intersect(Point p1, Point p2, Point p3, Point p4, Point& intersection){

bool parallel;

pair u = line_intersect(p1,p2,p3,p4,parallel);

if (parallel || u.first < 0 || u.first > 1 || u.second < 0 || u.second > 1) return false;

intersection.x = p1.x + u.first*(p2.x - p1.x);

intersection.y = p1.y + u.first*(p2.y - p1.y);

return true;

}
//------------------------------------------------------------------------------
void Polygon::add(Point p)

{

int np = number_of_points();
if (1
if (p==point(np-1)) error("polygon point equal to previous point");

bool parallel;

line_intersect(point(np-1),p,point(np-2),point(np-1),parallel);

if (parallel)

error("two polygon points lie in a straight line");

}
for (int i = 1; i
Point ignore(0,0);

if (line_segment_intersect(point(np-1),p,point(i-1),point(i),ignore))

error("intersect in polygon");

}


Closed_polyline::add(p);

}
//------------------------------------------------------------------------------
void Polygon::draw_lines() const

{

if (number_of_points() < 3) error("less than 3 points in a Polygon");

Closed_polyline::draw_lines();

}
//------------------------------------------------------------------------------
void Open_polyline::draw_lines() const

{

if (fill_color().visibility()) {

fl_color(fill_color().as_int());

fl_begin_complex_polygon();

for(int i=0; i
fl_vertex(point(i).x, point(i).y);

}

fl_end_complex_polygon();

fl_color(color().as_int()); // reset color

}

if (color().visibility())

Shape::draw_lines();

}
//------------------------------------------------------------------------------
void Closed_polyline::draw_lines() const

{

Open_polyline::draw_lines(); // first draw the "open poly line part"

// then draw closing line:

if (color().visibility())

fl_line(point(number_of_points()-1).x,

point(number_of_points()-1).y,

point(0).x,

point(0).y);

}
//------------------------------------------------------------------------------
void draw_mark(Point xy, char c)

{

static const int dx = 4;

static const int dy = 4;
string m(1,c);

fl_draw(m.c_str(),xy.x-dx,xy.y+dy);

}
//------------------------------------------------------------------------------
void Marked_polyline::draw_lines() const

{

Open_polyline::draw_lines();

for (int i=0; i
draw_mark(point(i),mark[i%mark.size()]);

}
//------------------------------------------------------------------------------
void Rectangle::draw_lines() const

{

if (fill_color().visibility()) { // fill

fl_color(fill_color().as_int());

fl_rectf(point(0).x,point(0).y,w,h);

fl_color(color().as_int()); // reset color

}
if (color().visibility()) { // lines on top of fill

fl_color(color().as_int());

fl_rect(point(0).x,point(0).y,w,h);

}

}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Point Circle::center() const

{

return Point(point(0).x+r, point(0).y+r);

}
//------------------------------------------------------------------------------
void Circle::draw_lines() const

{

if (fill_color().visibility()) { // fill

fl_color(fill_color().as_int());

fl_pie(point(0).x,point(0).y,r+r-1,r+r-1,0,360);

fl_color(color().as_int()); // reset color

}
if (color().visibility()) {

fl_color(color().as_int());

fl_arc(point(0).x,point(0).y,r+r,r+r,0,360);

}

}
//------------------------------------------------------------------------------
void Ellipse::draw_lines() const

{

if (fill_color().visibility()) { // fill

fl_color(fill_color().as_int());

fl_pie(point(0).x,point(0).y,w+w-1,h+h-1,0,360);

fl_color(color().as_int()); // reset color

}
if (color().visibility()) {

fl_color(color().as_int());

fl_arc(point(0).x,point(0).y,w+w,h+h,0,360);

}

}
//------------------------------------------------------------------------------
void Text::draw_lines() const

{

int ofnt = fl_font();

int osz = fl_size();

fl_font(fnt.as_int(),fnt_sz);

fl_draw(lab.c_str(),point(0).x,point(0).y);

fl_font(ofnt,osz);

}
//------------------------------------------------------------------------------
Axis::Axis(Orientation d, Point xy, int length, int n, string lab) :

label(Point(0,0),lab)

{

if (length<0) error("bad axis length");

switch (d){

case Axis::x:

{

Shape::add(xy); // axis line

Shape::add(Point(xy.x+length,xy.y));
if (0
int dist = length/n;

int x = xy.x+dist;

for (int i = 0; i
notches.add(Point(x,xy.y),Point(x,xy.y-5));

x += dist;

}

}

// label under the line

label.move(length/3,xy.y+20);

break;

}

case Axis::y:

{

Shape::add(xy); // a y-axis goes up

Shape::add(Point(xy.x,xy.y-length));
if (0
int dist = length/n;

int y = xy.y-dist;

for (int i = 0; i
notches.add(Point(xy.x,y),Point(xy.x+5,y));

y -= dist;

}

}

// label at top

label.move(xy.x-10,xy.y-length-10);

break;

}

case Axis::z:

error("z axis not implemented");

}

}
//------------------------------------------------------------------------------
void Axis::draw_lines() const

{

Shape::draw_lines();

notches.draw(); // the notches may have a different color from the line

label.draw(); // the label may have a different color from the line

}
//------------------------------------------------------------------------------
void Axis::set_color(Color c)

{

Shape::set_color(c);

notches.set_color(c);

label.set_color(c);

}
//------------------------------------------------------------------------------
void Axis::move(int dx, int dy)

{

Shape::move(dx,dy);

notches.move(dx,dy);

label.move(dx,dy);

}
//------------------------------------------------------------------------------
Function::Function(Fct f, double r1, double r2, Point xy,

int count, double xscale, double yscale)

// graph f(x) for x in [r1:r2) using count line segments with (0,0) displayed at xy

// x coordinates are scaled by xscale and y coordinates scaled by yscale

{

if (r2-r1<=0) error("bad graphing range");

if (count <=0) error("non-positive graphing count");

double dist = (r2-r1)/count;

double r = r1;

for (int i = 0; i
add(Point(xy.x+int(r*xscale),xy.y-int(f(r)*yscale)));

r += dist;

}

}
//------------------------------------------------------------------------------
bool can_open(const string& s)

// check if a file named s exists and can be opened for reading

{

ifstream ff(s.c_str());

return ff;

}
//------------------------------------------------------------------------------
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
Suffix::Encoding get_encoding(const string& s)

{

struct SuffixMap

{

const char* extension;

Suffix::Encoding suffix;

};
static SuffixMap smap[] = {

{".jpg", Suffix::jpg},

{".jpeg", Suffix::jpg},

{".gif", Suffix::gif},

};
for (int i = 0, n = ARRAY_SIZE(smap); i < n; i++)

{

int len = strlen(smap[i].extension);
if (s.length() >= len && s.substr(s.length()-len, len) == smap[i].extension)

return smap[i].suffix;

}
return Suffix::none;

}
//------------------------------------------------------------------------------
// somewhat over-elaborate constructor

// because errors related to image files can be such a pain to debug

Image::Image(Point xy, string s, Suffix::Encoding e)

:w(0), h(0), fn(xy,"")

{

add(xy);
if (!can_open(s)) { // can we open s?

fn.set_label("cannot open \""+s+'\"');

p = new Bad_image(30,20); // the "error image"

return;

}
if (e == Suffix::none) e = get_encoding(s);
switch(e) { // check if it is a known encoding

case Suffix::jpg:

p = new Fl_JPEG_Image(s.c_str());

break;

case Suffix::gif:

p = new Fl_GIF_Image(s.c_str());

break;

default: // Unsupported image encoding

fn.set_label("unsupported file type \""+s+'\"');

p = new Bad_image(30,20); // the "error image"

}

}
//------------------------------------------------------------------------------
void Image::draw_lines() const

{

if (fn.label()!="") fn.draw_lines();
if (w&&h)

p->draw(point(0).x,point(0).y,w,h,cx,cy);

else

p->draw(point(0).x,point(0).y);

}
//------------------------------------------------------------------------------
} // of namespace Graph_lib
1   2   3


GUI.cpp
//

// This is a GUI support code to the chapters 12-16 of the book

// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup

//
#include

#include

#include

#include "GUI.h"

#include "Simple_window.h"

#include "Emploer.h"

#include "windows.h"

namespace Graph_lib {

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

void Button::attach(Window& win)

{

pw = new Fl_Button(loc.x, loc.y, width, height, label.c_str());

pw->callback(reinterpret_cast(do_it), &win); // pass the window

own = &win;

}
//------------------------------------------------------------------------------
int In_box::get_int()

{

Fl_Input& pi = reference_to(pw);

// return atoi(pi.value());

const char* p = pi.value();

if (!isdigit(p[0])) return -999999;

return atoi(p);

}
//------------------------------------------------------------------------------
string In_box::get_string()

{

Fl_Input& pi = reference_to(pw);

return string(pi.value());

}
//------------------------------------------------------------------------------
void In_box::attach(Window& win)

{

pw = new Fl_Input(loc.x, loc.y, width, height, label.c_str());

own = &win;

}
void In_box::put(const string& s)

{

reference_to(pw).value(s.c_str());

}
//------------------------------------------------------------------------------
void Out_box::put(const string& s)

{

reference_to(pw).value(s.c_str());

}
//------------------------------------------------------------------------------
void Out_box::attach(Window& win)

{

pw = new Fl_Output(loc.x, loc.y, width, height, label.c_str());

own = &win;

}
//------------------------------------------------------------------------------
int Menu::attach(Button& b)

{

b.width = width;

b.height = height;
switch(k) {

case horizontal:

b.loc = Point(loc.x+offset,loc.y);

offset+=b.width;

break;

case vertical:

b.loc = Point(loc.x,loc.y+offset);

offset+=b.height;

break;

}

selection.push_back(b); // b is NOT OWNED: pass by reference

return int(selection.size()-1);

}
//------------------------------------------------------------------------------
int Menu::attach(Button* p)

{

Button& b = *p;

b.width = width;

b.height = height;
switch(k) {

case horizontal:

b.loc = Point(loc.x+offset,loc.y);

offset+=b.width;

break;

case vertical:

b.loc = Point(loc.x,loc.y+offset);

offset+=b.height;

break;

}

selection.push_back(&b); // b is OWNED: pass by pointer

return int(selection.size()-1);

}
int input = 0;

int id_search = -2;

int result_search = 0;

int temp_search = 0;

bool r_search = false;

int edit_id = -1;

bool edit_ = false;

vector tree;

vector del_img;

vector search_res;

bool tree_print = false;

bool cls = false;

bool cls2 = true;

bool test_string_to_not_number(string ss)

{

int len = ss.length();

for (int i=0; i
if ((ss[i]<'0' || ss[i] > '9') && ss[i]!='.') return true;

return false;

}

Del::Del(Point xy, int w, int h, const string& title):Window(xy,w,h,title),yes_button(Point(x_max()/2-80,y_max()/2),70,20,"Да",cb_yes),no_button(Point(x_max()/2,y_max()/2),70,20,"Нет",cb_no),sms(Point(60,y_max()/2-20),"Уверены что хотите удалить?"){

attach(sms);

attach(yes_button);

attach(no_button);

}

void Del::cb_yes(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).yes();

}

void Del::yes()

{

Employer_class* uk = Employer_class::First;

while (uk)

{

if (uk->i == edit_id) {

Employer_class::del(uk);

MessageBox (0,L"Сотрудник удален",L"Удаление",MB_OK);

input = 0;

id_search = -2;

result_search = 0;

temp_search = 0;

r_search = false;

edit_id = -1;

edit_ = false;

}

uk = uk->Next;

}

hide();

}

void Del::cb_no(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).no();

}

void Del::no()

{

hide();

}

Disc_windows::Disc_windows(Point xy, int w, int h, const string& title):Window(xy,w,h,title),exit_button(Point(x_max()-100,10),70,20,"Закрыть",cb_exit),in_button(Point(x_max()-100,50),70,20,"Записать",cb_in_dc),ou_button(Point(x_max()-100,90),70,20,"Считать",cb_ou_dc),in_name_dc(Point(80,10),400,20,"Имя"),massage_disc(Point(80,300),400,20,"")

{

attach(in_name_dc);

attach(in_button);

attach(ou_button);

attach(massage_disc);

attach(exit_button);

}

void Disc_windows::cb_exit(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).exit();

}

void Disc_windows::exit()

{

hide();

}
void Disc_windows::cb_in_dc(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).in_dc();

}

void Disc_windows::in_dc()

{

ostringstream ss;

Employer_class* uk = Employer_class::First;

if (Employer_class::empty()) ss << "Список пуст! ";

else {

string name = in_name_dc.get_string();

ofstream ofs(name.c_str());

if (!ofs) ss << "Файл не открыт! Ошибка...";

else {

while(uk!=NULL)

{

ofs.write(as_bytes(*uk), sizeof(Employer_class));

uk = uk->Next;

}

ss<< "Данные записаны...";

ofs.close();

}

}

massage_disc.put(ss.str());

}

void Disc_windows::cb_ou_dc(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).ou_dc();

}

void Disc_windows::ou_dc()

{

ostringstream ss;

string name = in_name_dc.get_string();

ifstream ifs(name.c_str());

Employer_class* empl = NULL;

empl = new Employer_class("0","0",0,0.0,"");

if (!ifs) ss << "Ошибка открытия файла!";

else {

while (ifs.read(as_bytes(*empl), sizeof(Employer_class)))

{

Employer_class::add(empl);

empl = new Employer_class("0","0",0,0.0,"");

}

ss << "Данные считаны...";

ifs.close();

}

massage_disc.put(ss.str());

}

Employer::Employer(Point xy, int w, int h, const string& title):Window(xy,w,h,title),

quit_button(Point(x_max()-70,0),70,20,"Выход",cb_quit),

sort_button(Point(x_max()-70,0),70,20,"Сортировать",cb_sort),

del_button(Point(x_max()-70,60),70,20,"Удалить",cb_del),

clear_button(Point(x_max()-150,30),70,20,"Очистить",cb_clear),

edit_button(Point(x_max()-270,30),110,20,"Редактировать",cb_edit),

search_button(Point(x_max()-70,30),70,20,"Поиск",cb_search),

add_button(Point(x_max()-310,0),70,20,"Добавить",cb_add),

in_button(Point(x_max()-230,0),70,20,"Вывести",cb_in),

dc_button(Point(x_max()-150,0),70,20,"Диск",cb_dc),

graph_button(Point(x_max()-150,0),70,20,"График",cb_garph),

in_name(Point(80,10),150,20,"Имя"),

in_family(Point(80,40),150,20,"Фамилия"),

in_age(Point(80,70),80,20,"Лет"),

in_salary(Point(80,100),150,20,"Оклад"),

in_photo(Point(80,130),150,20,"Путь"),

img(Point(300, 10),"Photo.jpg"),

menu(Point(0,y_max()-20),x_max()/10,20,Menu::horizontal,"Menu"),

xy_out(Point(100,400),x_max()-150,20,"Сотрудник"){

attach(in_name);

attach(in_family);

attach(in_age);

attach(in_salary);

attach(in_photo);

menu.attach(add_button);

menu.attach(in_button);

menu.attach(clear_button);

menu.attach(dc_button);

menu.attach(search_button);

menu.attach(edit_button);

menu.attach(del_button);

menu.attach(sort_button);

menu.attach(graph_button);

menu.attach(quit_button);

attach(img);

attach(menu);

attach(xy_out);

}

void Employer::cb_search(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).search();

}
bool check_string(string first, string second)

{

int first_length = first.length();

int second_length = second.length();

if (second_length == 0) return false;

int i = 0, j = 0;

while (i < first_length || j < second_length)

{

if (j == second_length) break;

if (second[j] == '*' && j == second_length - 1) { i = first_length; j = second_length; break; }

if (second[j] == '*') {

for (; second[j] == '*' && j < second_length; j++);

if (j == second_length) break;

int sj = 0;

for (; second[j+ sj] != '*' && j+sj < second_length && second[j + sj] != '?'; sj++);

string temp = second.substr(j, sj);

int find = first.find(temp);

if (find > 1) i = find;

}

if (first[i]=='?' && second[j] != '?') break;

else if (first[i] != second[j] && second[j] != '?') break;

if (i < first_length) i++;

if (j < second_length) j++;

}

if (first_length == i && second_length == j) return true;

else false;

}

void Employer::search()

{

ostringstream ss;

if (r_search == false)

{

string name = in_name.get_string();

string surname = in_family.get_string();

string photo = in_photo.get_string();

int age = -9999;

double salary = -9999.99;

if (in_age.get_string() != "")

if(!test_string_to_not_number(in_age.get_string())) age = in_age.get_int();

if (in_salary.get_string() != "")

if (!test_string_to_not_number(in_salary.get_string())) salary = atof((in_salary.get_string()).c_str());
if (name != "" && surname != "" && photo != "")

{

Employer_class* uk = Employer_class::First;

while(uk)

{

if (age != -9999 || salary != -9999.99) {

if (check_string(uk->name, name) && check_string(uk->family, surname) && check_string(uk->photo, photo) && (uk->age == age || salary == uk->salary) ){ search_res.push_back(uk); result_search++; cout << result_search; }

}

else

if (check_string(uk->name, name) && check_string(uk->family, surname) && check_string(uk->photo, photo)){ search_res.push_back(uk); result_search++; cout << result_search; }

uk = uk->Next;

}

r_search = true;

ss<<"Сотрудников найдено "<< result_search;

}

else ss<<"Поля не заполнены, используйте * и ? для использовяния маски";

}

else

{

for (int i = 0; i < search_res.size(); i++)

{

if (id_search == search_res.size()-1) {id_search = -2; i = 0; cout << id_search;}

if (i > id_search)

{

cls2 = false;

Employer::clear();

cls2 = true;

ss<family << " Имя: " <name << " Возраст: " << search_res[i]->age <salary << "р";

if (!del_img.empty())

{

delete del_img[0];

del_img.erase(del_img.begin());

}

Image* DDD = new Image(Point(0,0),search_res[i]->photo);

del_img.push_back(DDD);

//cout<
Employer::img.p = DDD->p;

Employer::attach(Employer::img);

id_search = i;

edit_id = search_res[i]->i;

break;

}

}

if (result_search == 0)ss<<"Сотрудников найдено "<< result_search;

}

xy_out.put(ss.str());

}

void Employer::cb_clear(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).clear();

}

void Employer::clear()

{

detach(in_name);

detach(in_family);

detach(in_age);

detach(in_salary);

detach(in_photo);

detach(xy_out);

detach(img);

if (!del_img.empty()) {

delete del_img[0];

del_img.erase(del_img.begin());

}

Image* DDD = new Image(Point(0,0),"Photo.jpg");

del_img.push_back(DDD);

img.p = DDD->p;

attach(img);

attach(in_name);

attach(in_family);

attach(in_age);

attach(in_salary);

attach(in_photo);

attach(xy_out);

if (cls2)

{

id_search = -2;

result_search = 0;

temp_search = 0;

r_search = false;

edit_id = -1;

edit_ = false;

search_res.clear();

}

if (!cls)

{

input = 0;

}

}

void Employer::cb_quit(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).quit();

}

void Employer::quit()

{

hide();

}

void Employer::cb_garph(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).graph();

}

int Frst_sim (double n)

{

int x = n;

while (x>10)

{

x /= 10;

}

return x;

}

int Razr(double n)

{

int x = n;

int i = 1;

while (x>10)

{

x /= 10;

i*=10;

}

return i;

}

void Employer::graph()

{
if (Employer_class::empty()) MessageBox (0,L"Список пустой",L"Ошибка",MB_OK);

else {

int x_ofset = 100;

int y_ofset = 60;

int x_space = 40;

int y_space = 40;

int base_month = 1;

int end_month = Employer_class::number;

const int x_max =1200;

const int y_max = 600;

const int x_centr = x_max/2;

const int y_centr = y_max/2;

const Point centr(x_centr, y_centr);

const int r_min = -10;

const int r_max = 11;

const int xlength = x_max - 40;

const int ylength = y_max - 80;

const int n_points = 400;

const int x_scale = double(xlength)/(end_month);

const int y_scale = double(ylength)/Employer_class::salary_max;

Simple_window grf(Point(100,100),x_max,y_max,"Skip");

Scale xs(x_ofset,base_month,x_scale);

Scale ys(y_max-y_ofset,0,-0.5);

int x1 = x_ofset;

int y1 = y_ofset;

Axis xa(Axis::x,Point(x_ofset,y_max-y_ofset),xlength,Employer_class::number,"");

grf.attach(xa);

Axis ya(Axis::y,Point(x_ofset,y_max-y_ofset),ylength,10,"");

grf.attach(ya);

Vector_ref T;

for (int i = 100; i<=1000; i+=100)

{

ostringstream ss;

ss << i;

T.push_back(new Text (Point(50,ys(i)-2),ss.str()));

grf.attach(T[i/100-1]);

}

Open_polyline skip;

Employer_class* uk = Employer_class::First;

Vector_ref TT;

Vector_ref TT2;

while (uk != NULL)

{

ostringstream ss;

int salary = uk->salary;

skip.add(Point(xs(uk->i+1),ys(salary)-2));

TT.push_back(new Text(Point(xs(uk->i+1),ylength+50),uk->name));

grf.attach(TT[uk->i]);

ss<salary;

string s = ss.str();

TT2.push_back(new Text(Point(xs(uk->i+1),ys(salary)-2),s));

grf.attach(TT2[uk->i]);

uk = uk->Next;

}

grf.attach(xa);

grf.attach(ya);

grf.attach(skip);

grf.wait_for_button();

}

detach(xy_out);

attach(xy_out);

}

void Employer::cb_sort(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).sort();

}

void Employer::sort()

{

Sort_window str(Point(200,200),600,400,"Сортировка");

gui_main();

}

void Employer::cb_edit(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).edit();

}

void Employer::edit()

{

Employer_class* uk = Employer_class::First;

if (edit_id != -1 && edit_ == true){

while (uk != NULL)

{

if (uk->i == edit_id){

uk->family = in_family.get_string();

uk->name = in_name.get_string();

uk->age = in_age.get_int();

uk->salary = atof((in_salary.get_string()).c_str());

uk->photo = in_photo.get_string();

edit_id = -1;

edit_ = false;

Employer::clear();

MessageBox (0,L"Содрудник отредактирован",L"Редактирование",MB_OK);

break;

}

uk = uk->Next;

}

}

else if (edit_id >= 0){

edit_ = true;

while (uk!=NULL)

{

if (uk->i == edit_id){

ostringstream s;

s<age;

ostringstream ss;

ss<salary;

in_name.put((uk->name).c_str());

in_family.put((uk->family).c_str());

in_age.put(s.str());

in_salary.put(ss.str());

in_photo.put((uk->photo).c_str());

break;

}

uk = uk->Next;

}

MessageBox (0,L"Содрудник для редактирования выбран",L"Редактирование",MB_OK);

}

else MessageBox (0,L"Сотрудник не выбран",L"Ошибка",MB_OK);

}

void Employer::cb_add(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).add();

}

void Employer::add()

{

if (in_family.get_string() == "" || in_name.get_string() == "" || in_age.get_int() <0 || atof((in_salary.get_string()).c_str()) <0 || in_name.get_string() == "" || test_string_to_not_number(in_salary.get_string())) MessageBox (0,L"Не корректные данные",L"Ошибка",MB_OK);

else{

Employer_class* temp = NULL;

temp = new Employer_class("0","0",0,0.0,in_photo.get_string());

temp->family = in_family.get_string();

temp->name = in_name.get_string();

temp->age = in_age.get_int();

string s = in_salary.get_string();

temp->salary = atof(s.c_str());

//temp->photo = new Image(Point(300,300),);

Employer_class::add(temp);

Employer::clear();

}

}

void Employer::cb_in(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).in();

}

void Employer::in()

{

ostringstream ss;

Employer::detach(Employer::img);

cls = true;

Employer::clear();

cls = false;

if (!Employer_class::empty()) {

Employer_class* uk = Employer_class::First;

while (uk != NULL)

{

if (uk->i == input){

ss<i+1<<'-'<number<< " | Фамилия: " << uk->family << " | Имя: " <name << " | Возраст: " <age << " | Зарплата: " << uk->salary << "р";

edit_id = uk->i;

if (!del_img.empty()) {

delete del_img[0];

del_img.erase(del_img.begin());

}

Image* DDD = new Image(Point(0,0),uk->photo);

del_img.push_back(DDD);

//cout<
Employer::img.p = DDD->p;

Employer::attach(Employer::img);

input++;

break;

}

uk = uk->Next;

}

if (uk->i == uk->number-1) input = 0;

}

else ss << "Список пустой!";

xy_out.put(ss.str());

}

void Employer::cb_dc(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).dc();

}

void Employer::dc()

{

Disc_windows dsc(Point(200,200),600,400,"Работа с диском");

gui_main();

}

void Employer::cb_del(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).del();

}

void Employer::del()

{

if (edit_id == -1) MessageBox (0,L"Сотрудник не выбран",L"Ошибка",MB_OK);

else {

Del del_win(Point(200,200),300,100,"Удаление");

detach(xy_out);

attach(xy_out);

gui_main();

}

}
Sort_window::Sort_window(Point xy, int w, int h, const string& title):

Window(xy,w,h,title),

quit_button(Point(0,0),70,20,"Выход",cb_quit),

sort_button(Point(0,0),70,20,"Сортировать",cb_sort),

input_button(Point(0,0),70,20,"Вывести",cb_input),

save_button(Point(0,0),70,20,"Сохранить",cb_save),

output(Point(100,200),x_max()-150,20,"Сотрудник"),

pole(Point(x_max()-90,170),40,20,"Выберите сортируемое поле"),

pole_0(Point(30,20),"Сортировать по Имени: 1"),

pole_1(Point(30,50),"Сортировать по Фамилии: 2"),

pole_2(Point(30,80),"Сортировать по Возрасту: 3"),

pole_3(Point(30,110),"Сортировать по Зарплате: 4"),

menu(Point(0,y_max()-20),x_max()/4,20,Menu::horizontal,"Menu")

{

menu.attach(input_button);

menu.attach(sort_button);

menu.attach(save_button);

menu.attach(quit_button);

attach(pole_0);

attach(pole_1);

attach(pole_2);

attach(pole_3);

attach(pole);

attach(menu);

attach(output);

Binary_Tree::del_tree(Binary_Tree::Tree);

tree.clear();

tree_print = false;

}
void Sort_window::cb_quit(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).quit();

}

void Sort_window::quit()

{

hide();

}

void Sort_window::cb_sort(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).sort();

}

void Sort_window::sort()

{

ostringstream ss;

if (!Employer_class::empty()) {

if (pole.get_int()>0 && pole.get_int()<5){

Employer_class* uk = Employer_class::First;

while (uk != NULL)

{

Binary_Tree::create_tree(uk, Binary_Tree::Tree, pole.get_int()-1);

uk = uk->Next;

}

ss<<"Данные отсортированны!";

}

else ss<<"Выбранно не корректтное поле!";

}

else ss << "Список пустой!";

output.put(ss.str());

}

void Sort_window::cb_input(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).input_sort();

}

void Sort_window::input_sort()

{

ostringstream ss;

if (!Employer_class::empty()) {

if (tree_print == false && !Employer_class::empty()) {

Binary_Tree::print_tree(Binary_Tree::Tree,tree);

tree_print = true;

input = 0;

}

if (tree.size() > 0){

ss<< "Фамилия: " << (tree[input])->family << " Имя: " << tree[input]->name << " Возраст: "<< tree[input]->age <salary << "р";

input++;

if (input == tree.size()) input = 0;

}

else ss<<"Данные не отсортированны!";

}

else ss<<"Список пустой!";

output.put(ss.str());

}

void Sort_window::cb_save(Graph_lib::Address, Graph_lib::Address pw)

{

reference_to (pw).save();

}

void Sort_window::save()

{

ostringstream ss;

if (tree_print == true){

Employer_class* uk = Employer_class::First;

Employer_class* temp = NULL;

while (uk != NULL)

{

Employer_class::del(uk);

uk = uk->Next;

}

for (int i = 0; i < tree.size(); i++)

{

temp = new Employer_class(tree[i]->name,tree[i]->family,tree[i]->age,tree[i]->salary,tree[i]->photo);

Employer_class::add(temp);

}

ss<<"Отсортированный список сохранен!";

Binary_Tree::del_tree(Binary_Tree::Tree);

tree.clear();

}

else ss<<"Список не отсортирован!";

output.put(ss.str());

}

///////////////////////////////////////////////////////////////

}; // of namespace Graph_lib
Исполнение программы



Главный экран



Вывод



Добавление



Считывание с диска



Поиск



Редактирование



Удаление



Сортировка



График
Заключение

В ходе написание этой программы я разобрался с некоторыми структурами данных, такими как связный список и бинарное дерево. Поработал с библиотекой FLTK, разобрался как работает низкоуровневый графический интерфейс. Закрепил знания ООП. Коснулся callback программирования. И закрепил знания, полученные на практике.

Список используемой литературы

  1. Хабрахабр: [Электронный ресурс]. 2006-2017. URL: https://habrahabr.ru

  2. CyberForum.ru - форум программистов и сисадминов: [Электронный ресурс]. 2000 – 2017. URL: http://www.cyberforum.ru

  3. Stack Overflow: [Электронный ресурс]. 2017. URL: http://stackoverflow.com

  4. Stack Overflow на русском: [Электронный ресурс]. 2017. URL: http://ru.stackoverflow.com



0>0>
1   2   3