MyTetra Share
Делитесь знаниями!
ChaineRs delete varient
Время создания: 14.05.2017 23:02
Раздел: Poetry
Запись: xintrea/mytetra_db_mcold/master/base/14947921394fsqwy14n5/text.html на raw.githubusercontent.com
# coding: utf-8


import gi

import SendKeys
from peewee import *
gi.require_version(
'Gtk', '3.0')
import gi.repository.Gtk as Gtk



file =
'resource.txt'
db = SqliteDatabase('ChaineRs.db')

# Model for database

class Chain(Model):
id = IntegerField(
unique=True)
c_item = CharField()
id_root = IntegerField()
id_parent = IntegerField()
id_previous = IntegerField()
id_next = IntegerField()
b_root = BooleanField()
# True = root of branch -> c_item = Name of branch

class Meta:
database = db

def next_id(instance):
# find max value of temp_id in model
# increment it by one and assign it to model instance object
try:
e = instance.
__name__ + '.select(fn.Max(' + instance.__name__ + '.id))[0].id + 1'
# next_value = Poet.select(fn.Max(Poet.id))[0].id + 1
next_value = eval(e)
except:
next_value =
1
return next_value

class HeaderBarWindow(Gtk.ApplicationWindow):
d_data =
dict()
l_data =
list()
n_cur =
0 # cursor to 1-st element of l_data -> self.l_data[self.n_cur]
id = 0 # current id
id_level = 0 # level parentage by default
id_root = 0
id_previous = 0
id_next = -1
id_paramount = 0 # id of chosen root for filter
b_to_update = False # define to update or to save item

root = ''



def __init__(self, *args, **kwargs):
super(HeaderBarWindow, self).__init__(*args, **kwargs)

self.set_border_width(10)
self.set_default_size(400, 100) # size of window

hb = Gtk.HeaderBar() # TitleBar
hb.set_show_close_button(True)
#hb.props.title = "ChaineR"
self.set_titlebar(hb)

# number of rows and columns in table
n_row = 9
n_col = 9

# level of buttons
y_level_1 = int(n_row / 2)
y_level_2 = y_level_1 +
1

table = Gtk.Table(n_row, n_col, True)

# ComboBox
self.name_store = Gtk.ListStore(int, str)
self.name_combo = Gtk.ComboBox.new_with_model_and_entry(self.name_store)
# insert roots
l_combo = self.take_roots()
for i in range(len(l_combo)):
self.name_store.append([1, l_combo[i]]) # TODO: change 1 to new id
# TODO: do likewise
# data depends of chosen root
self.name_combo.connect("changed", self.take_data)
self.name_combo.set_entry_text_column(1)

hb.add(
self.name_combo)

# button add root
self.b_add_root = Gtk.Button('+')
hb.add(
self.b_add_root)
self.b_add_root.connect("clicked", self.insert_root, None)

# filter
self.find_entry = Gtk.Entry()
table.attach(
self.find_entry, 0, 3, 0, 1)
self.find_entry.connect('key_press_event', self.find_like, None) # enter event

# button left
self.b_left = Gtk.Button("<")
#self.b_left.add(Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.NONE))
table.attach(self.b_left, 0, 1, y_level_1, y_level_2)

# editor
self.entry = Gtk.Entry()
# self.entry.connect('key_press_event', self.rewrite, None) # write data
table.attach(self.entry, 1, n_col - 1, y_level_1, y_level_2)

# button right
self.b_right = Gtk.Button(">")
#self.b_right.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE))
table.attach(self.b_right, n_col - 1, n_col, y_level_1, y_level_2)
self.b_right.connect("clicked", self.take_child, None)

# button up
self.b_up = Gtk.Button()
self.b_up.add(Gtk.Arrow(Gtk.ArrowType.UP, Gtk.ShadowType.NONE))
table.attach(
self.b_up, int(n_col / 2), int(n_col / 2) + 1, 0, 1)
self.b_up.connect("clicked", self.take_prev, None)

# button down
self.b_down = Gtk.Button()
self.b_down.add(Gtk.Arrow(Gtk.ArrowType.DOWN, Gtk.ShadowType.NONE))
table.attach(
self.b_down, int(n_col / 2), int(n_col / 2) + 1, n_row - 1, n_row)
self.b_down.connect("clicked", self.take_next, None)

# button for save data
self.b_save = Gtk.Button("Save")
table.attach(
self.b_save, n_col - 1, n_col, n_row - 1, n_row)
self.b_save.connect("clicked", self.rewrite, None)

# button for delete item
self.b_delete = Gtk.Button("Delete")
table.attach(
self.b_delete, 0, 1, n_row - 1, n_row)
self.b_delete.connect("clicked", self.delete_item, None)

# label previous
self.l_prev = Gtk.Label()
table.attach(
self.l_prev, 1, n_col - 1, y_level_1 - 2, y_level_1 - 1)

# label next
self.l_next = Gtk.Label()
table.attach(
self.l_next, 1, n_col - 1, y_level_2 + 1, y_level_2 + 2)

self.add(table)


def take_data(self, combo):
"""
Take data of the root chosen of user
And write to controlls
:return:
"""
if not self.entry.get_text() == '': # если происходит смена root-а то записываем изменения
self.insert_or_update_row()


# hide buttons
self.b_up.hide()
#self.b_down.hide()
self.b_left.hide()
#self.b_right.hide()

# make empty data
d = dict()
self.d_data = d
l =
list()
self.l_data = l

# make empty controlls
self.empty_controlls()

# переписываем уровень с предком в качестве рута
#
TODO: при смещении вправо предком нужно записывать предыдущий элемент
# take_data используется только в первоначальной загрузке поэтому пишу сюда
self.id_level = self.id_root

# переписываем уровень с предком в качестве предыдущего элемента
self.id_previous = self.id_root

tree_iter = combo.get_active_iter()
if tree_iter != None:
model = combo.get_model()
row_id
, self.root = model[tree_iter][:2]
try:
self.take_id_root() # define self.id_root by self.root
#print(self.id_level)
# take data of the root
self.select_data() # select data to self.d_data and self.l_data
except:
pass
#print("Can't find root")
#print("self.n_cur - " + str(self.n_cur))
#if l: # contain objects
# write to controlls
# self.write_to_controlls_default()

def select_data(self):
"""
Function select data and set text to controllers
Take id root and id level of objects of this root
:return:
"""
#self.test_print()
for c in Chain.select().where(Chain.id_root == self.id_root and Chain.id_parent == self.id_root).order_by(
Chain.id.asc()):
self.d_data[c.id] = c.c_item # insert data into dictionary
self.l_data.append(c.id) # write id-s to list for circle
# set text to controllers
#try:
# self.entry.set_text(self.d_data[self.l_data[0]])
#except:
# pass
#try:
# self.l_next.set_label(self.d_data[self.l_data[1]])
#except:
# pass



if self.l_data[0]:
self.rewrite_class_data(self.l_data[0]) # прописываем данные по 1-ому элементу если он есть
self.write_cont_first() # прописываем контроллы
self.b_to_update = True # as it is -> just to update item
#self.test_print()
else:
print("Im here")
self.empty_controlls()
self.id = next_id(Chain)
self.id_previous = 0
self.take_id_root()
self.id_parent = 0
#elf.id_next = 0
#elf.b_root = False
if not self.l_data:
print("and here")
self.empty_controlls()
self.id = next_id(Chain)
self.id_previous = 0
self.take_id_root()
self.id_parent = 0
self.id_next = 0
self.b_root = False

# устанавливаем видимость кнопки если есть следующий
if self.have_next():
self.b_down.set_visible(True)

# устанавливаем видимость кнопки потомка если есть потомок
if self.have_child():
self.b_right.set_visible(True)
else:
self.b_right.set_label("+")
self.b_right.set_visible(True)

if not self.find_entry == '':
self.find_like()

def write_to_controlls_default(self):
"""
Function write data into controlls in default loading
:return:
"""
#self.n_cur = self.l_data[0] # cursor into 1-st element list of data
#self.l_prev.set_label(self.d_data[self.n_cur - 1])
#print("self.d_data - " + str(self.d_data))
#print("self.l_data - " + str(self.l_data))
#print("self.n_cur - " + str(self.n_cur))
self.entry.set_text(self.d_data[self.l_data[self.n_cur]])
try:
self.l_next.set_label(self.d_data[self.l_data[self.n_cur + 1]])
except:
self.l_next.set_label('') # empty if not exist

def write_to_controlls(self):
"""
Function write data into controlls
:return:
"""
self.l_prev.set_label(self.d_data[self.l_data[self.n_cur - 1]])
self.entry.set_text(self.d_data[self.l_data[self.n_cur]])
try:
self.l_next.set_label(self.d_data[self.l_data[self.n_cur + 1]])
except:
self.l_next.set_label('') # empty if not exist

def write_nothing_to_controlls(self):
"""
Function write data into controlls
:return:
"""
#print("self.n_cur - " + str(self.n_cur))
self.l_prev.set_label(self.d_data[self.l_data[self.n_cur - 1]])
self.entry.set_text('') # empty if not exist
# self.l_next.set_label('') # empty if not exist

def rewrite_data(self):
f =
open(file, 'w')
l_data =
list()
num =
1 # number of line
for i in range(1, len(self.d_data.items())):
l_data.append(
self.d_data[str(i)])
for i in range(len(l_data)):
line =
str(num) + '--' + l_data[i] + '\n'
f.write(line)
num = num +
1
f.close()

def write_data(self, button, data=None):
f =
open(file, 'w')
l_data =
list()
num =
1 # number of line
for i in range(1, len(self.d_data.items())):
l_data.append(
self.d_data[str(i)])
for i in range(len(l_data)):
line =
str(num) + '--' + l_data[i] + '\n'
f.write(line)
num = num +
1
f.close()

# заведение записи через entry
# работает
def rewrite(self, button=0, event=0, data=None):
"""
Function rewrite/write data in controll entry-editor
:param button:
:param event:
:param data:
:return:
"""

# if row exist -> rewrite
# else insert

self.insert_or_update_row()
# make visible button
self.b_down.set_visible(True)

def delete_item(self, button=0, event=0, data=None):
"""
Delete item from system
:param button:
:param event:
:param data:
:return:
"""
# rewrite relationships
# update id_next for previous item
Chain.update(**{'id_next': self.id_next}).where(Chain.id == self.id_previous).execute()

# update id_previous for next item
Chain.update(**{'id_previous': self.id_previous}).where(Chain.id == self.id_next).execute()

if not self.id_next == -1:
t_id_next =
self.id_next # temp variable for delete item
# delete item
#Chain.delete().where(Chain.id == self.id).execute()

# move to next
self.id = t_id_next
self.rewrite_class_data()
self.write_cont() # rewrite controlls
else: # if last item
# delete item
#Chain.delete().where(Chain.id == self.id).execute()
self.entry.set_text("")

def select_dict_id(self, id_item):
"""
Function take dictionary of values of taken id
:return:
"""
d = dict()

c = Chain.get(Chain.id == id_item)
d[
'id'] = c.id
d[
'c_item'] = c.c_item
d[
'id_root'] = c.id_root
d[
'id_parent'] = c.id_parent
d[
'id_previous'] = c.id_previous
d[
'id_next'] = c.id_next
d[
'b_root'] = c.b_root
return d

def rewrite_class_data(self, id_item=None):
"""
Function rewrite data from id data in DB
"""
if id_item == None:
id_item =
self.id
d =
self.select_dict_id(id_item)
self.id = d['id']
self.id_root = d['id_root']
self.id_level = d['id_parent']
self.id_previous = d['id_previous']
self.id_next = d['id_next']
self.root = d['c_item']
return

def
insert_row(self, id_item=None):
"""
Insert row
:return:
"""
if id_item == None:
id_item = next_id(Chain)
Chain.create(
id=id_item, c_item=self.entry.get_text(), id_parent=self.id_level, id_previous=self.id_previous, b_root=False)

def insert_or_update_row(self, id_item=None):
"""
Function insert or update row
:return:
"""
#if self.entry.get_text() == '':
# return
if id_item == None:
id_item = next_id(Chain)
if self.b_to_update == False: # if not just update -> insert otherwise -> update
Chain.create(id=id_item, c_item=self.entry.get_text(), id_root=self.id_root, id_parent=self.id_level, id_previous=self.id_previous, id_next=-1, b_root=False)
self.rewrite_class_data(id_item)
else:
Chain.update(**{
'c_item': self.entry.get_text()}).where(Chain.id == self.id).execute()
try:
Chain.update(**{
'id_next': self.id}).where(Chain.id == self.id_previous).execute()
except:
print("None previous element!")
pass


def
write_root(self, combo):
### insert & update text in controls
tree_iter = combo.get_active_iter()
if tree_iter != None:
model = combo.get_model()
name_item = model[tree_iter][:1]
### TODO: update controlls
else:
entry = combo.get_child()
cv_item = entry.get_text()
# text from ListStore - ComboBox
idv_parent = 0
idv_previous = 0
# insert data
Chain.create(id=next_id(Chain), c_item=cv_item, id_parent=idv_parent, id_previous=idv_previous, b_root=True)

def on_maximize_toggle(self, action, value):
action.set_state(value)
if value.get_boolean():
self.maximize()
else:
self.unmaximize()

def take_next(self, button, data=None):
"""
Take next item
:param button:
:param data:
:return:
"""
self.b_up.set_visible(True)

self.insert_or_update_row()

text =
self.entry.get_text()
self.empty_controlls()
# перезаписываем предыдущий label текущим entry
self.l_prev.set_label(text)

# делаем пустым entry
self.entry.set_text("")

# сохраняем id как id_previous
self.id_previous = self.id

# если есть следующий элемент, то переписываем данные и переписываем контроллы
if self.have_next():
#self.insert_or_update_row()
self.id = self.id_next
self.rewrite_class_data()
self.test_print()
self.write_cont()
self.b_to_update = True # as it is -> just to update item
else:
self.b_to_update = False # as it is -> insert item

# устанавливаем видимость кнопки если есть следующий
if self.have_next():
self.b_down.set_visible(True)

def take_prev(self, button, data=None):
"""
Go to previous items
Change text in items
Work from signal of button
:param button: b_prev
:param data: None
:return:
"""
# перезаписываем entry текущим label previous
# self.entry.set_text(self.l_prev.get_text())
self.insert_or_update_row()

if self.have_previous():
# перезаписываем label next текущим entry
self.l_next.set_label(self.entry.get_text())
self.id = self.id_previous
self.rewrite_class_data()
self.write_cont()
if not self.have_previous():
self.b_up.hide()
# устанавливаем видимость кнопки если есть следующий
# устанавливаем видимость кнопки если есть следующий
if self.have_next():
self.b_down.set_visible(True)
self.b_to_update = True # as it is -> just to update item
else:
self.b_to_update = False # just to insert

def take_child(self, button, data=None):
self.empty_controlls() # clear controlls

# change id_parent
self.id_level = self.id

# show child if it is
if self.have_child(): # if he has a child
self.b_to_update = True # can just update
self.rewrite_class_data(self.select_first_child())
self.write_cont()
# else empty
else:
self.b_to_update = False # can just insert

def take_parent(self, button, data=None):
self.empty_controlls()

# меняем id_parent
self.id = self.id_level
self.rewrite_class_data() # переписываем данные


def on_name_combo_changed(self, combo):
"""
Function for work with combo
:param combo: control ComboBox
:return:
"""
tree_iter = combo.get_active_iter()
if tree_iter != None:
model = combo.get_model()
row_id, name = model[tree_iter][:2]
#print("Selected: ID=%d, name=%s" % (row_id, name))
else:
entry = combo.get_child()
### TODO: insert into database root row



def find_like(self, button=0, event=0, data = None):
"""
Find item which like data in filter
:param button:
:param event:
:param data:
:return:
"""
if not self.entry.get_text() == '': # если происходит фильтрация
self.insert_or_update_row()

entry =
self.name_combo.get_child()
if entry.get_text() == '': # make paramount = 0 if it is empty
self.id_paramount = 0

### TODO: find object in hole database -> change parent_id
text_to_find = self.find_entry.get_text().decode("utf-8") # take text from textview

d_all = dict()

l_name =
list() # list to find objects
l_name.append(text_to_find)
l_d =
list()


# if root is not None -> use in select
entry = self.name_combo.get_child()
paramount_item = entry.get_text()
# print(str(self.id_paramount) + " " + str(paramount_item))
if not self.id_paramount==0 and not paramount_item == "":
for c in Chain.select().where(Chain.id_root == self.id_paramount):
if not c.b_root == 1: # not use root items
d_all[c.id] = c.c_item # take all data in database
else:
for c in Chain.select():
if not c.b_root == True: # not use root items
d_all[c.id] = c.c_item # take all data in database
d_all[c.id] = c.c_item # take all data in database

# print(d_all)
for k, v in d_all.items(): # combine list of values from dictionary
l_d.append(v)
for i in range(len(l_d)):
set_d =
set(l_d[i]) # set of each element of dictionary
for j in range(len(l_name)):
set_l =
set(l_name[j])
inter = set_d.intersection(set_l)
l_i = len(inter)
if len(inter) == len(set(l_name[j])):
for k, v in d_all.items():
if v == l_d[i]:
res = k
# take key
if not self.is_root(int(res)):
self.rewrite_class_data(int(res))
self.write_cont()
self.b_to_update = True # if it is -> just update
if self.have_previous(self.id_previous):
self.b_up.set_visible(True)
else:
self.b_up.hide()
if self.id_previous == 0:
self.b_up.hide()
# self.test_print()
return


#### functions for work with SQLite
def cur_level(self):
"""
Define level of current object
:param n_id: id of current object
:return: id parent
"""
try:
c = Chain.get(Chain.id ==
self.n_cur)
self.id_level = c.id_parent
except:
pass

def
sel_max(self):
"""
Take maximum id for current level
:return: None
"""
# TODO: rewrite for use in multi tree structure
query = Chain.select(fn.max(Chain.id)).where(Chain.id_parent == self.id_level)
return query.count()

def sel_min(self):
"""
Take maximum id for current level
:return: None
"""
# TODO: rewrite for use in multi tree structure
query = Chain.select(fn.min(Chain.id)).where(Chain.id_parent == self.id_level)
for c in Chain.select().where(Chain.id_parent == self.id_level).order_by(Chain.id.asc()):
res = c.id
return res


def insert_root(self, button, data=None):
### insert & update text in controls

tree_iter
= self.name_combo.get_active_iter()
try:
entry =
self.name_combo.get_child()
cv_item = entry.get_text()
# text from ListStore - ComboBox
idv_parent = 0
idv_previous = 0
# insert data
Chain.create(id=next_id(Chain), c_item=cv_item, id_root=self.id_root, id_parent=idv_parent, id_previous=idv_previous, id_next = -1, b_root=True)
self.name_store.append([1, cv_item])
except:
pass
self.empty_controlls()

def insert_row_entry(self, button, data=None):
"""
Function insert row into DB from entry-editor
:param button:
:param data:
:return:
"""
Chain.create(id=next_id(Chain), c_item=self.entry.get_text(), id_root=self.id_root, id_parent=self.id_level, id_previous=self.id_previous, b_root=False)

def insert_row_entry_rewrite(self):
"""
Function insert row into DB from entry-editor
:param button:
:param data:
:return:
"""
Chain.create(id=next_id(Chain), c_item=self.entry.get_text(), id_root=self.id_root, id_parent=self.id_level, id_previous=self.id_previous, b_root=False)

def take_roots(self):
"""
Function take list of roots
:return:
"""
l = list()
try:
for c in Chain.select().where(Chain.b_root==True):
l.append(c.c_item)
except:
pass
return
l

# определение id_root
def take_id_root(self):
"""
Function set id of root
:return:
"""
entry = self.name_combo.get_child()
self.root = entry.get_text()
for c in Chain.select().where(Chain.c_item == self.root, Chain.b_root == 1):
self.id_root = c.id
self.id_level = c.id
self.id_previous = 0
self.id_next = -1
self.b_root = False

# set paramount id of chosen root
self.id_paramount = self.id_root
return

# скрываем данные в контроллах
def empty_controlls(self):
"""
Make empty controlls
:return:
"""
text = u""
self.entry.set_text(text)
self.l_prev.set_label(text)
self.l_next.set_label(text)

# Фунции записи контроллов
def write_cont_first(self):
"""
Запись контроллов при первичной загрузке
:return:
"""
self.empty_controlls() # очищаем контроллы

self.entry.set_text(self.get_text_of_id(self.id))
self.l_next.set_label(self.get_text_of_id(self.id_next))

def write_cont(self):
"""
Запись контроллов по текущим параметрам экземпляра
self.id
self.id_next
self.id_previous
:return:
"""
self.empty_controlls() # очищаем контроллы

self.entry.set_text(self.get_text_of_id(self.id))
self.l_next.set_label(self.get_text_of_id(self.id_next))
self.l_prev.set_label(self.get_text_of_id(self.id_previous))

def get_text_of_id(self, id_item):
"""
Определение текста по id
:return:
"""
if id_item == 0 or id_item == -1: # если id пустое то возвращаем пустую запись
return ""
c = Chain.get(Chain.id == id_item)
return c.c_item

def have_next(self):
"""
Определение наличия следующего элемента
:return:
"""
c = Chain.get(Chain.id == self.id)
if c.id_next > 0:
return True
else:
return False

def have_previous(self, id_item=None):
"""
Определение наличия предыдущего элемента
:return:
"""
if id_item==None:
id_item =
self.id

for c in Chain.select().where(Chain.id == id_item):
if c.id_previous > 0:
return True
else:
return False

def have_parent(self, id_item=None):
"""
Определение наличия предка
:return:
"""
if id_item==None:
id_item =
self.id
c = Chain.select().where(Chain.id == id_item)
if c.id_parent > 0:
return True
else:
return False

def have_child(self, id_parent_item=None):
"""
Определение наличия потомков
:return:
"""
if id_parent_item == None:
id_parent_item =
self.id
c = Chain.select().where(Chain.id_root ==
self.id_root and Chain.id_parent == id_parent_item).order_by(
Chain.id.asc())
if c:
return True
else:
return False

def take_first_child(self, id_root_item=None, id_parent_item=None):
"""
Определение id 1-ого потомка
:return:
"""
if id_root_item == None:
id_root_item =
self.id_root
if id_parent_item == None:
id_parent_item =
self.id_parent
c = Chain.select().where(Chain.id_root == id_root_item
and Chain.id_parent == id_parent_item).order_by(
Chain.id.asc()).limit(
1)
return c.id

def is_last(self, id_root_item=None, id_parent_item=None):
"""
Define current item is last in this level
:return:
"""
if id_root_item == None:
id_root_item =
self.id_root
if id_parent_item == None:
id_parent_item =
self.id_parent
query =
self.select(fn.max(Chain.id)).where(Chain.id_root == id_root_item and Chain.id_parent == id_parent_item).order_by(
Chain.id.desc())
#max = query.count()
if self.id == query.count():
return True
else:
return False

def is_root(self, id_item=None):
"""
Define is id_item root
:param id_item:
:return:
"""
if id_item == None:
id_item =
self.id
for c in Chain.select().where(Chain.b_root==1):
if c.id == id_item:
return True
return False

def select_first_child(self, id_item=None):
"""
Return id of first child item
:param id_item:
:return:
"""
if id_item == None:
id_item =
self.id
for c in Chain.select().where(Chain.id_parent == id_item).order_by(Chain.id.asc()):
print(str(self.id) + " " + str(c.id))
return c.id

def quit(self, button=0, data=None):
"""
Rewrite data and quit from application
:return:
"""
if not self.entry.get_text() == '':
self.insert_or_update_row() # update current row

Gtk.main_quit()

def test_print(self):
"""
Test output data function
:return:
"""
print("self.id - " + str(self.id))
print("self.id_root - " + str(self.id_root))
print("self.id_level - " + str(self.id_level))
print("self.id_previous - " + str(self.id_previous))
print("self.id_next - " + str(self.id_previous))






if __name__ == '__main__':
try:
Chain.create_table()
# создаем таблицу
except:
pass
#try:
# test_insert()
#except:
# pass
win = HeaderBarWindow()
#win.connect("delete-event", Gtk.main_quit)
win.connect("delete-event", win.quit)
win.show_all()
Gtk.main()
Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования