Добавлен: 17.03.2024
Просмотров: 11
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Министерство образования, науки и молодежной политики Забайкальского края
Государственное профессиональное образовательное учреждение
«ЧИТИНСКИЙ ТЕХНИКУМ ОТРАСЛЕВЫХ ТЕХНОЛОГИЙ И БИЗНЕСА» (ГПОУ «ЧТОТиБ»)
Курсовое проектирование по теме «Объектно-ориентированное программирование»
МДК 01.02 раздела «Прикладное программирование»
ПМ1 «Разработка программных модулей программного обеспечения для компьютерных систем»
«Локальная база данных»
Выполнил
_____________Т.Н. Устинов
студент группы ПКС-14-1
«___»__________2017 г.
Руководитель работы
_____________Т.М. Смирнова
«___»__________2017 г.
2017 г.
Содержание
1.
Введение
Цель и задачи курсового проектирования
Данный проект был разработан исключительно в учебных целях, при его создании не преследовались не какие другие цели. Потому что этот проект является локальной базой данных, аналогово которой большое множество которые удобнее и более функциональные.
Цель выполнения данного курсового проекта была в том, чтобы закрепить понятие концепции объектно-ориентированного программирования, изучить как устроены высокоуровневые визуальные системы разработки программ, и затронуть разработку программы с примитивным графическим интерфейсом.
Тема проекта «Локальная база данных Сотрудники» была выбрана потому что как пример она хорошо подходит, но не более. У этой программы простые типы хранимых данных, и можно реализовать много функций обработки этой базы.
Теоретическая часть
Данная база хранит сотрудников, рабочих и в принципе может хранить что угодно, с информацией о каждом сотруднике.
Хранит информацию:
-
Имя
-
Фамилия
-
Количество лет
-
Оклад
-
Фото (точнее путь на фото)
Реализованы функции:
-
Вывод сотрудников
-
Добавление новых сотрудников
-
Сохранение базы в бинарный файл
-
Поиск
-
Редактирование
-
Удаление
-
Сортировка
-
И вывод графика по зарплате
Для организации структуры в оперативной памяти использовался связный список. Связный список — это базовая динамическая структура данных в информатике, состоящая из узлов, каждый из которых содержит как собственно данные, так и одну или две ссылки («связки») на следующий и/или предыдущий узел списка. Принципиальным преимуществом перед массивом является структурная гибкость: порядок элементов связного списка может не совпадать с порядком расположения элементов данных в памяти компьютера, а порядок обхода списка всегда явно задаётся его внутренними связями. И собственные данные в узле являются переменная типа 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; i void 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; }
Министерство образования, науки и молодежной политики Забайкальского края
Государственное профессиональное образовательное учреждение
«ЧИТИНСКИЙ ТЕХНИКУМ ОТРАСЛЕВЫХ ТЕХНОЛОГИЙ И БИЗНЕСА» (ГПОУ «ЧТОТиБ»)
Курсовое проектирование по теме «Объектно-ориентированное программирование»
МДК 01.02 раздела «Прикладное программирование»
ПМ1 «Разработка программных модулей программного обеспечения для компьютерных систем»
«Локальная база данных»
Выполнил
_____________Т.Н. Устинов
студент группы ПКС-14-1
«___»__________2017 г.
Руководитель работы
_____________Т.М. Смирнова
«___»__________2017 г.
2017 г.
Содержание
1.
Введение
Цель и задачи курсового проектирования
Данный проект был разработан исключительно в учебных целях, при его создании не преследовались не какие другие цели. Потому что этот проект является локальной базой данных, аналогово которой большое множество которые удобнее и более функциональные.
Цель выполнения данного курсового проекта была в том, чтобы закрепить понятие концепции объектно-ориентированного программирования, изучить как устроены высокоуровневые визуальные системы разработки программ, и затронуть разработку программы с примитивным графическим интерфейсом.
Тема проекта «Локальная база данных Сотрудники» была выбрана потому что как пример она хорошо подходит, но не более. У этой программы простые типы хранимых данных, и можно реализовать много функций обработки этой базы.
Теоретическая часть
Данная база хранит сотрудников, рабочих и в принципе может хранить что угодно, с информацией о каждом сотруднике.
Хранит информацию:
-
Имя
-
Фамилия
-
Количество лет
-
Оклад
-
Фото (точнее путь на фото)
Реализованы функции:
-
Вывод сотрудников
-
Добавление новых сотрудников
-
Сохранение базы в бинарный файл
-
Поиск
-
Редактирование
-
Удаление
-
Сортировка
-
И вывод графика по зарплате
Для организации структуры в оперативной памяти использовался связный список. Связный список — это базовая динамическая структура данных в информатике, состоящая из узлов, каждый из которых содержит как собственно данные, так и одну или две ссылки («связки») на следующий и/или предыдущий узел списка. Принципиальным преимуществом перед массивом является структурная гибкость: порядок элементов связного списка может не совпадать с порядком расположения элементов данных в памяти компьютера, а порядок обхода списка всегда явно задаётся его внутренними связями. И собственные данные в узле являются переменная типа 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; iИмя
Фамилия
Количество лет
Оклад
Фото (точнее путь на фото)
Вывод сотрудников
Добавление новых сотрудников
Сохранение базы в бинарный файл
Поиск
Редактирование
Удаление
Сортировка
И вывод графика по зарплате
{
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
vector
vector
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);
}
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
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);
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() { }
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
// treat an address as a reference to a W
{
return *static_cast
}
//------------------------------------------------------------------------------
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
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
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
{
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
}
parallel = false;
return pair
((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
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
own = &win;
}
//------------------------------------------------------------------------------
int In_box::get_int()
{
Fl_Input& pi = reference_to
// 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
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
}
//------------------------------------------------------------------------------
void Out_box::put(const string& s)
{
reference_to
}
//------------------------------------------------------------------------------
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
vector
vector
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
}
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
}
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
}
void Disc_windows::exit()
{
hide();
}
void Disc_windows::cb_in_dc(Graph_lib::Address, Graph_lib::Address pw)
{
reference_to
}
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
}
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
}
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 << " Имя: " <
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
}
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
}
void Employer::quit()
{
hide();
}
void Employer::cb_garph(Graph_lib::Address, Graph_lib::Address pw)
{
reference_to
}
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
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
Vector_ref
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<
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
}
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
}
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<
ostringstream ss;
ss<
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
}
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
}
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<
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
}
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
}
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
}
void Sort_window::quit()
{
hide();
}
void Sort_window::cb_sort(Graph_lib::Address, Graph_lib::Address pw)
{
reference_to
}
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
}
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 <
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
}
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 программирования. И закрепил знания, полученные на практике.
Список используемой литературы
-
Хабрахабр: [Электронный ресурс]. 2006-2017. URL: https://habrahabr.ru -
CyberForum.ru - форум программистов и сисадминов: [Электронный ресурс]. 2000 – 2017. URL: http://www.cyberforum.ru -
Stack Overflow: [Электронный ресурс]. 2017. URL: http://stackoverflow.com -
Stack Overflow на русском: [Электронный ресурс]. 2017. URL: http://ru.stackoverflow.com
1 2 3