using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.ComponentModel.Design; using System.Drawing.Design; using System.IO; using DevExpress.XtraTreeList; using DevExpress.XtraTreeList.Nodes; using Atechnology.Components; using Atechnology.DBConnections2; using System.Windows.Forms.Design; namespace Atechnology.Components.Tree { public partial class AtTreeListControl : TreeList { public static int idcurrentpeople = 0; #region Delegates #region Menu events delegates /// Добавление основной группы /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuAddMain_Click_Delegate(); /// Добавление дочерней группы /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuAddChild_Click_Delegate(DataRow CurrentRow); /// Переименование группы /// Текущая строка датасета /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuRename_Click_Delegate(DataRow CurrentRow); /// Удаление группы /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuRemove_Click_Delegate(DataRow CurrentRow); /// Перемещение группы /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuMove_Click_Delegate(DataRow CurrentRow); /// Перемещение группы в корень /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuSetMain_Click_Delegate(DataRow CurrentRow); /// Добавление фильтра /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuAddFilter_Click_Delegate(DataRow CurrentRow); /// Настройка фильтра /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuSetupFilter_Click_Delegate(DataRow CurrentRow); /// Дублирование группы(фильтра) и вложенной структуры /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuDublicateStructure_Click_Delegate(DataRow CurrentRow); /// Дублирование группы(фильтра), вложенной структуры и данных /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuDublicateData_Click_Delegate(DataRow CurrentRow); /// Перемещение группы вверх(сортировка) /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuMoveUp_Click_Delegate(DataRow CurrentRow); /// Перемещение группы вниз(сортировка) /// Текущая выделенная группа(фильтр) /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuMoveDown_Click_Delegate(DataRow CurrentRow); /// Клик по любому пункту меню /// Имя пункта меню /// Текст пункта меню /// Выделенная группа /// Необходимость выполнени стандартного кода обработки события public delegate bool MenuItem_Click_Delegate(string MenuItemName, string MenuItemText, DataRow SelectedRow); #endregion #region Base methods delegate public delegate void LoadDocsDelegate(int idgroup); public delegate void LoadCurrentGroupDocsDelegate(); public delegate void LoadGroupDelegate(int idpeople, int iddocappearance); public delegate string LoadFilterDelegate(); public delegate void LoadPictureDelegate(string strFilter); public delegate bool SaveToBaseDelegate(); public delegate void SaveToBaseGroupDelegate(DataRow dr); #endregion public delegate void MoveItemDelegate(DataRow drGroup); #endregion #region MenuEvents public event MenuAddMain_Click_Delegate MenuAddMain_Click; public event MenuAddChild_Click_Delegate MenuAddChild_Click; public event MenuRename_Click_Delegate MenuRename_Click; public event MenuRemove_Click_Delegate MenuRemove_Click; public event MenuMove_Click_Delegate MenuMove_Click; public event MenuSetMain_Click_Delegate MenuSetMain_Click; public event MenuAddFilter_Click_Delegate MenuAddFilter_Click; public event MenuSetupFilter_Click_Delegate MenuSetupFilter_Click; public event MenuDublicateStructure_Click_Delegate MenuDublicateStructure_Click; public event MenuDublicateData_Click_Delegate MenuDublicateData_Click; public event MenuMoveUp_Click_Delegate MenuMoveUp_Click; public event MenuMoveDown_Click_Delegate MenuMoveDown_Click; public event MenuItem_Click_Delegate MenuItem_Click; #endregion #region Enums /// Сторона перемещения группы public enum NodeMoveDirection { MoveUp = -1, // Вверх MoveDown = 1 // Вниз } #endregion #region Variables private DataRow MoveGroup = null; // Перемещаемая группа private DataRow[] _MoveItems = null; // Перещаемый набор документов bool isKeyMove = false; // Перменная для перемещения групп клавиатурой public DataTable TableGroup; // Таблица групп public DataTable TableDoc; // Таблица документов string _DocTableName = ""; // Имя таблицы документов private string _PrimaryKeyName = ""; // Имя первичного ключа таблицы групп public bool saving = false; // Для запрещения действий в событии смены ноды bool isAddFilter = false; // Для запрещения действий при добавлении фильтра string _DataRelation; // Имя связи таблицы групп с собой же string StoreDM = ""; // Переменная для промежуточного хранения DataMember dbconn db; // Соединение с базой bool _IsSupportFilter = true; public DevExpress.XtraGrid.Views.Grid.GridView GridView; DataRow oldNode; #region Methods delegate public LoadDocsDelegate LoadDocs; public LoadCurrentGroupDocsDelegate LoadCurrentGroupDocs; public LoadGroupDelegate LoadGroup; public LoadFilterDelegate LoadFilter; public SaveToBaseDelegate SaveToBase; public SaveToBaseGroupDelegate SaveToBaseGroup; public LoadPictureDelegate LoadPictures; public MoveItemDelegate MoveItem; #endregion #region Grants public bool GroupAdd = true; public bool GroupEdit = true; public bool GroupRemove = true; public bool FilterEdit = true; #endregion #endregion #region Constructors and initialisation public AtTreeListControl() { InitializeComponent(); MenuGroup.Opening += new CancelEventHandler(MenuGroup_Opening); MenuGroupAddFilter.Click += new EventHandler(MenuGroupAddFilter_Click); MenuGroupMove.Click += new EventHandler(MenuGroupMove_Click); MenuGroupMoveDown.Click += new EventHandler(MenuGroupMoveDown_Click); MenuGroupMoveUp.Click += new EventHandler(MenuGroupMoveUp_Click); MenuGroupSetMain.Click += new EventHandler(MenuGroupSetMain_Click); MenuGroupSetupFilter.Click += new EventHandler(MenuGroupSetupFilter_Click); MenuGroupAddMain.Click += new EventHandler(MenuGroupAddMain_Click); MenuGroupAddChild.Click += new EventHandler(MenuGroupAddChild_Click); MenuGroupRemove.Click += new EventHandler(MenuGroupRemove_Click); MenuGroupRename.Click += new EventHandler(MenuGroupRename_Click); MenuGroupDublicateStructure.Click += new EventHandler(MenuGroupDublicateStructure_Click); MenuGroupDublicateData.Click += new EventHandler(MenuGroupDublicateData_Click); foreach (ToolStripItem mnu in MenuGroup.Items) { if (mnu is ToolStripSeparator || mnu == MenuGroupAddFilter || mnu == MenuGroupMove || mnu == MenuGroupMoveDown || mnu == MenuGroupMoveUp || mnu == MenuGroupSetMain || mnu == MenuGroupSetupFilter || mnu == MenuGroupAddMain || mnu == MenuGroupAddChild || mnu == MenuGroupRemove || mnu == MenuGroupRename || mnu == MenuGroupDublicateStructure || mnu == MenuGroupDublicateData ) { continue; } mnu.Click += new EventHandler(mnu_Click); } FocusedNodeChanged += new FocusedNodeChangedEventHandler(AtTreeListControl_FocusedNodeChanged); KeyDown += new KeyEventHandler(AtTreeListControl_KeyDown); LostFocus += new EventHandler(AtTreeListControl_LostFocus); Click += new EventHandler(AtTreeListControl_Click); LoadDocs = LoadDocsMethod; LoadCurrentGroupDocs = LoadDocsMethod; LoadGroup = LoadGroupMethod; LoadFilter = LoadFilterMethod; SaveToBase = SaveToBaseMethod; SaveToBaseGroup = SaveToBaseGroupMethod; MoveItem = MoveItemMethod; InitData(); SelectImageList = imageListGroup; } public override void BeginInit() { base.BeginInit(); } public override void EndInit() { MenuGroupAddFilter.Visible = _IsSupportFilter; MenuGroupSetupFilter.Visible = _IsSupportFilter; MenuGroupSeparator3.Visible = _IsSupportFilter; base.EndInit(); } #endregion #region Properties #region Visisble properties /// Таблица документов [Category("Data")] [Description("Gets or sets a specific list in a data source whose data is displayed by the TreeList control.")] [DefaultValue("")] [Localizable(true)] [Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor))] public string DocTable { get { return _DocTableName; } set { _DocTableName = value; if (ds == null) return; TableDoc = ds.Tables[value]; } } /// Связь таблицы групп с собой же(для дублированния и какскадного удаления) [Category("Data")] [Description("Gets or sets a specific list in a data source whose data is displayed by the TreeList control.")] [DefaultValue("")] [Localizable(true)] [Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor))] public string DataRelation { get { return _DataRelation; } set { _DataRelation = value; } } /// Заголовок колонки в дереве [Category("AT")] public string ColumnText { get { return colname.Caption; } set { colname.Caption = value; } } /// Список иконок для дерева [Category("AT")] public ImageList imlist { get { return imageListGroup; } set { } } /// Поддерживает фильтры [Category("AT")] public bool IsSupportFilter { get { return _IsSupportFilter; } set { _IsSupportFilter = value; } } #endregion #region Unvisible properties /// Соединение с БД [Category("1.atProperty")] [Browsable(false)] public dbconn Connection { get { return db; } set { db = value; } } /// DataSet которому принадлежат таблицы [Browsable(false)] public DataSet ds { get { return (DataSet)DataSource; } } /// Имя поля PrymaryKey таблицы групп [Browsable(false)] [Category("1.atProperty")] public string PrimaryKeyName { get { if (_PrimaryKeyName == "") { if (TableGroup != null && TableGroup.PrimaryKey.Length != 0) _PrimaryKeyName = TableGroup.PrimaryKey[0].ColumnName; else _PrimaryKeyName = KeyFieldName; } return _PrimaryKeyName; } set { _PrimaryKeyName = value; } } /// Имя поля PrymaryKey таблицы документов [Browsable(false)] private string DocPrimaryKey { get { if (TableDoc == null || TableDoc.PrimaryKey.Length == 0) return ""; return TableDoc.PrimaryKey[0].ColumnName; } } /// Массив документов для перемещения в группу [Browsable(false)] public DataRow[] MoveItems { get { return _MoveItems; } set { if (value == null || value.Length == 0) return; Cursor = Cursors.Hand; _MoveItems = value; } } /// Имя таблицы документов [Browsable(false)] public string TableDocName { get { if (TableDoc == null) return ""; return TableDoc.TableName.Replace("_view", "").Replace("view_", ""); } } /// Связь таблицы групп с собой же(для дублированния и какскадного удаления) [Browsable(false)] public DataRelation RelationGroup { get { if (DataRelation == null || DataRelation == "") return GetRelation(); string relName = DataRelation.Replace(TableGroup.TableName + ".", ""); if (relName.Length == 0) return GetRelation(); return ds.Relations[relName]; } } /// Признак что таблица групп является сортируемой по numpos [Browsable(false)] public bool IsNumposed { get { return (TableGroup.Columns["numpos"] != null); } } #endregion #region Override properties /// Таблица групп [Category("Data")] [Description("Gets or sets a specific list in a data source whose data is displayed by the TreeList control.")] [DefaultValue("")] [Localizable(true)] [Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor))] public new string DataMember { get { return base.DataMember; } set { if (ds != null) { TableGroup = ds.Tables[value]; if (TableGroup != null && TableGroup.PrimaryKey.Length != 0) { PrimaryKeyName = TableGroup.PrimaryKey[0].ColumnName; KeyFieldName = PrimaryKeyName; } } base.DataMember = value; } } /// Источник данных [AttributeProvider(typeof(IListSource))] [DefaultValue("")] [Description("Gets or sets the object used as the data source for the current TreeList control.")] [Category("Data")] public new object DataSource { get { return base.DataSource; } set { base.DataSource = value; if (ds != null) { TableGroup = ds.Tables[DataMember]; if (TableGroup != null && TableGroup.PrimaryKey.Length != 0) { PrimaryKeyName = TableGroup.PrimaryKey[0].ColumnName; KeyFieldName = PrimaryKeyName; } if (_DocTableName != "") TableDoc = ds.Tables[_DocTableName]; } } } #endregion #endregion #region Events /// Обработка нажатий клавиш protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.Escape && (MoveItems != null || MoveGroup != null)) { MoveItems = null; MoveGroup = null; Cursor = Cursors.Default; } else if (keyData == Keys.Enter && (MoveItems != null || MoveGroup != null)) MoveElements(); else if (Focused) isKeyMove = true; return base.ProcessCmdKey(ref msg, keyData); } /// void AtTreeListControl_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter && (_MoveItems != null || MoveGroup != null)) MoveElements(); else { if (Selection.Count == 0) return; if (Selection[0] == null) return; switch (e.KeyCode) { case Keys.Right: Selection[0].Expanded = true; break; case Keys.Left: if (Selection[0].Expanded == false) if (Selection[0].Level != 0) FocusedNode = Selection[0].ParentNode; else Selection[0].Expanded = false; else Selection[0].Expanded = false; break; case Keys.Enter: if (Selection[0].Expanded) Selection[0].Expanded = false; else Selection[0].Expanded = true; break; } } } /// Нажатие кнопки в дереве private void AtTreeListControl_Click(object sender, EventArgs e) { isKeyMove = false; } /// Смена ветки в дереве public void AtTreeListControl_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e) { if (saving || MdiManager.openState) return; DataRow dr = GetSelectedNode(); if (dr == null) return; if (!isKeyMove) MoveElements(); isKeyMove = false; if (AtDataSet.GetFieldInt(dr, "typ") == 0) { LoadDocs((int)dr[PrimaryKeyName]); if (GridView != null && ((AtUserControl)(this.Parent)).NeedRestoreLayout) { DeleteTempRows(TableDoc); ((AtUserControl)(this.Parent)).RestoreLayoutControl(); ((AtUserControl)(this.Parent)).NeedRestoreLayout = false; ((AtUserControl)(this.Parent)).NeedSaveLayout = true; } } else LoadFilter(); oldNode = GetSelectedNode(); } /// Потеря фокуса private void AtTreeListControl_LostFocus(object sender, EventArgs e) { isKeyMove = false; } #endregion #region Methods #region Get and Find methods /// получение выделенного Node (Row) /// Объект TreeList /// public DataRow GetSelectedNode() { DataTable dtt = ((DataSet)(DataSource)).Tables[DataMember]; if (dtt == null) return null; if (FocusedNode == null || dtt.Rows.Count == 0) return null; if (GetDataRecordByNode(FocusedNode) == null) return null; return ((DataRowView)(GetDataRecordByNode(FocusedNode))).Row; } /// поиск ветки в дереве /// Начальная нода /// Имя поля /// /// public TreeListNode FindNode(TreeListNode node, string columnName, int id) { DevExpress.XtraTreeList.Nodes.TreeListNodes nn; DevExpress.XtraTreeList.Nodes.TreeListNode n_temp; if (node == null) nn = Nodes; else nn = node.Nodes; foreach (DevExpress.XtraTreeList.Nodes.TreeListNode n in nn) { DataRow dr = ((DataRowView)GetDataRecordByNode(n)).Row; if ((int)dr[columnName] == id) return n; if (n.Nodes.Count != 0) { n_temp = FindNode(n, columnName, id); if (n_temp != null) return n_temp; } } return null; } /// поиск ветки в дереве /// Объект TreeList /// Начальная нода /// Оюъект в источнике данных который нужно найти в дереве /// Найденая нода public TreeListNode FindNode(TreeListNode node, object obj) { DevExpress.XtraTreeList.Nodes.TreeListNodes nn; DevExpress.XtraTreeList.Nodes.TreeListNode n_temp; if (node == null) nn = Nodes; else nn = node.Nodes; foreach (DevExpress.XtraTreeList.Nodes.TreeListNode n in nn) { if (GetDataRecordByNode(n) == obj) return n; if (n.Nodes.Count != 0) { n_temp = FindNode(n, obj); if (n_temp != null) return n_temp; } } return null; } /// получение списка вложенных datarow /// public List GetListNodesRows(TreeListNode node) { List d = new List(); d.Add(((DataRowView)GetDataRecordByNode(node)).Row); foreach (DevExpress.XtraTreeList.Nodes.TreeListNode n in node.Nodes) { if (n.Nodes.Count != 0) d.AddRange(GetListNodesRows(n)); else d.Add(((DataRowView)GetDataRecordByNode(n)).Row); } return d; } #endregion #region MoveNodes /// Перемещает ноду вверх/вниз (меняет numpos) /// Определяет в какую сторону перемещать public void NodeMove(NodeMoveDirection MoveDiraction) { if (!IsNumposed) return; DataRow dr = GetSelectedNode(); if (dr == null || TableGroup == null) return; Enabled = false; saving = true; SetNumPos(dr); string filtText = ""; if (dr["parentid"] == DBNull.Value) filtText = "parentid is null"; else filtText = "parentid = " + dr["parentid"].ToString(); DataRow[] drs = TableGroup.Select(filtText, "numpos"); for (int numpos = 0; numpos < drs.Length; numpos++) { if ((int)drs[numpos]["numpos"] != numpos + 1) drs[numpos]["numpos"] = numpos + 1; } drs = TableGroup.Select(filtText + " and numpos = " + ((int)dr["numpos"] + (int)MoveDiraction).ToString()); if (drs.Length != 0) drs[0]["numpos"] = (int)drs[0]["numpos"] - (int)MoveDiraction; dr["numpos"] = (int)dr["numpos"] + (int)MoveDiraction; if (PrimaryKeyName != "") { DevExpress.XtraTreeList.Nodes.TreeListNode nod = FindNode(null, PrimaryKeyName, (int)dr[PrimaryKeyName]); FocusedNode = nod; if (nod != null) nod.Expanded = false; } saving = false; Enabled = true; Focus(); } #endregion #region Работа с numpos /// Номализует numpos. заполняет дырки и устраняет null в numpos /// запись по которой определяется группа public void SetNumPos(DataRow row) { if (!IsNumposed) return; DataRow[] drsNull; DataRow[] drsNotNull; if (row.RowState == DataRowState.Detached) row.BeginEdit(); object parentid = (row.RowState == DataRowState.Deleted) ? row["parentid", DataRowVersion.Original] : row["parentid"]; if (row.RowState == DataRowState.Detached) row.EndEdit(); if (parentid == DBNull.Value) { drsNull = TableGroup.Select("numpos is null and parentid is null", PrimaryKeyName); drsNotNull = TableGroup.Select("numpos is not null and parentid is null", "numpos desc"); } else { drsNull = TableGroup.Select("numpos is null and parentid = " + parentid.ToString(), PrimaryKeyName); drsNotNull = TableGroup.Select("numpos is not null and parentid = " + parentid.ToString(), "numpos desc"); } int StartNumpos = 1; if (drsNotNull.Length != 0) StartNumpos = (int)drsNotNull[0]["numpos"]; foreach (DataRow dr in drsNull) dr["numpos"] = StartNumpos++; } /// Номализует numpos. заполняет дырки и устраняет null в numpos во всей таблице public void SetNumPos() { if (!IsNumposed) return; colnumpos.SortOrder = SortOrder.None; DataRow[] drs = TableGroup.Select("numpos is null"); while (drs.Length != 0) { SetNumPos(drs[0]); drs = TableGroup.Select("numpos is null"); } } #endregion #region Move Group /// Перемещает группу в указанную /// Группа в которую переносится public virtual void MoveElements(DataRow dr) { if (MoveGroup != null) { if (MoveGroup != dr) { saving = true; #region Установим numpos (если он есть) if (IsNumposed) { DataRow[] drs; if (dr == null) drs = TableGroup.Select("parentid is null", "numpos desc"); else drs = TableGroup.Select("parentid = " + dr[PrimaryKeyName].ToString(), "numpos desc"); int numpos = 1; if (drs.Length != 0) { if (drs[0]["numpos"] == DBNull.Value) SetNumPos(drs[0]); numpos = (int)drs[0]["numpos"] + 1; } MoveGroup["numpos"] = numpos; } #endregion if (dr != null) MoveGroup["parentid"] = dr[PrimaryKeyName]; else MoveGroup["parentid"] = DBNull.Value; saving = false; } Cursor = Cursors.Default; MoveGroup = null; } MoveItem(dr); } public virtual void MoveItemMethod(DataRow drGroup) { if (_MoveItems != null) { foreach (DataRow dr1 in _MoveItems) dr1[PrimaryKeyName] = drGroup[PrimaryKeyName]; Cursor = Cursors.Default; _MoveItems = null; SaveToBase(); GC.Collect(); GC.Collect(); } } /// Перемещает группу в выделенную public virtual void MoveElements() { DataRow dr = GetSelectedNode(); if (dr == null) return; if (_IsSupportFilter && dr["typ"] != DBNull.Value && Convert.ToInt32(dr["typ"]) != 0) return; MoveElements(dr); } #endregion #region Инициализация компонента public virtual void InitData(bool IsEmptyMethods) { InitData(); if (IsEmptyMethods) { LoadDocs = EmptyLoadDocsMethod; LoadGroup = EmptyLoadGroupMethod; } } public virtual void InitData() { InitData(dbconn._db); } public virtual void InitData(dbconn _db) { db = _db; if (ds != null) { TableGroup = ds.Tables[DataMember]; if (TableGroup != null && TableGroup.PrimaryKey.Length != 0) { PrimaryKeyName = TableGroup.PrimaryKey[0].ColumnName; KeyFieldName = PrimaryKeyName; } if (_DocTableName != "") TableDoc = ds.Tables[_DocTableName]; } } #endregion #region Selection methods /// Выделяет первую корневую ноду public virtual void SelectFirstNode() { if (this.Nodes.FirstNode != null) FocusedNode = Nodes.FirstNode; } /// Ищет и выделяет ноду /// Искомый объект в DataSource /// Выделенная нода public TreeListNode SelectNode(object obj) { TreeListNode node = FindNode(null, obj); if (node != null) { Selection.Clear(); FocusedNode = node; } return node; } /// Ищет и выделяет ноду /// Имя поля /// /// Выделенная нода public TreeListNode SelectNode(string columnName, int id) { TreeListNode node = FindNode(null, columnName, id); if (node != null) { Selection.Clear(); FocusedNode = node; } return node; } /// Ищет и выделяет ноду по PrimaryKey /// /// Выделенная нода public TreeListNode SelectNode(int id) { TreeListNode node = FindNode(null, PrimaryKeyName, id); if (node != null) { Selection.Clear(); FocusedNode = node; } return node; } #endregion #region Internal methods /// Получает связь таблицы групп с собой же(для дублированния и какскадного удаления) /// Найденную связь. null еслти не найдена private DataRelation GetRelation() { DataRelation result = null; if (DataRelation == "") { foreach (DataRelation drel in ds.Relations) { if (drel.ChildColumns.Length != 0 && drel.ChildColumns[0].ColumnName == "parentid" && drel.ParentColumns.Length != 0 && drel.ParentColumns[0].ColumnName == PrimaryKeyName) { result = drel; break; } } } return result; } /// Отключает и сохраняет DataMember(иначе сцука не работают многие операции) private void SaveDataMember() { saving = true; StoreDM = base.DataMember; base.DataMember = ""; } /// Восстанавливает DataMember private void RestoreDataMember() { base.DataMember = StoreDM; saving = false; } /// Позиционирование после удаления группы /// Удаляемая группа DataRow[] SetPositionBeforeDelete(DataRow dr) { if (!IsNumposed) return null; DataRow[] drs = null; int numpos = Useful.GetInt32(dr["numpos"]); if (dr["parentid"] == DBNull.Value) { drs = TableGroup.Select(PrimaryKeyName + " <> " + dr[PrimaryKeyName].ToString() + " and parentid is null and numpos >= " + numpos, "numpos"); if (drs.Length == 0) drs = TableGroup.Select(PrimaryKeyName + " <> " + dr[PrimaryKeyName].ToString() + " and parentid is null and numpos <= " + numpos, "numpos desc"); } else { drs = TableGroup.Select(PrimaryKeyName + " <> " + dr[PrimaryKeyName].ToString() + " and parentid = " + dr["parentid"].ToString() + " and numpos >= " + numpos, "numpos desc"); if (drs.Length == 0) drs = TableGroup.Select(PrimaryKeyName + " <> " + dr[PrimaryKeyName].ToString() + " and parentid = " + dr["parentid"].ToString() + " and numpos <= " + numpos, "numpos desc"); if (drs.Length == 0) drs = TableGroup.Select(PrimaryKeyName + " = " + dr["parentid"].ToString()); } return drs; } #endregion #endregion #region MenuGroup /// Открытие меню групп private void MenuGroup_Opening(object sender, CancelEventArgs e) { DataRow dr = GetSelectedNode(); if (dr == null) { MenuGroupAddChild.Enabled = false; MenuGroupDublicateStructure.Enabled = false; MenuGroupMove.Enabled = false; MenuGroupMoveDown.Enabled = false; MenuGroupMoveUp.Enabled = false; MenuGroupRemove.Enabled = false; MenuGroupRename.Enabled = false; MenuGroupSetMain.Enabled = false; MenuGroupSetupFilter.Enabled = false; } else { bool isFilt = _IsSupportFilter && (Useful.GetInt32(dr["typ"]) != 0); MenuGroupDublicateStructure.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupAdd); MenuGroupMove.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupEdit); MenuGroupMoveDown.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupEdit); MenuGroupMoveUp.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupEdit); MenuGroupRemove.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupRemove); MenuGroupRename.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupEdit); MenuGroupSetMain.Enabled = (isFilt && FilterEdit) || (!isFilt && GroupEdit); MenuGroupAddChild.Enabled = (!isFilt && GroupAdd); MenuGroupSetupFilter.Enabled = (isFilt && FilterEdit); if (isFilt) MenuGroupSetMain.Text = "Сделать фильтр основным"; else MenuGroupSetMain.Text = "Сделать группу основной"; } MenuGroupAddFilter.Enabled = FilterEdit; MenuGroupAddMain.Enabled = GroupAdd; } /// добавить основную группу private void MenuGroupAddMain_Click(object sender, EventArgs e) { #region Вызов событий if (MenuAddMain_Click != null) { if (!MenuAddMain_Click()) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupAddMain", MenuGroupAddMain.Text, GetSelectedNode())) return; } #endregion DataRow dr = TableGroup.NewRow(); dr[PrimaryKeyName] = dbconn.GetGenId("gen_" + DataMember); if (InputBox.ShowDialog("Создание основной группы", "Введите имя", "Введите комментарий", dr["name"].ToString(), "") == DialogResult.Cancel) return; SaveDataMember(); dr["name"] = InputBox.Value; dr["comment"] = InputBox.Value2; AtDataSet.SetFieldValue(dr, "typ", 0); AtDataSet.SetFieldValue(dr, "isload", 1); AtDataSet.SetFieldValue(dr, "guid", Guid.NewGuid()); TableGroup.Rows.Add(dr); SetNumPos(); RestoreDataMember(); } /// добавить дочернюю private void MenuGroupAddChild_Click(object sender, EventArgs e) { DataRow dr = GetSelectedNode(); #region Вызов событий if (MenuAddChild_Click != null) { if (!MenuAddChild_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupAddChild", MenuGroupAddChild.Text, dr)) return; } #endregion if (dr == null || (_IsSupportFilter && Useful.GetInt32(dr["typ"]) != 0)) return; DataRow dr1 = TableGroup.NewRow(); dr1[PrimaryKeyName] = dbconn.GetGenId("gen_" + DataMember); if (InputBox.ShowDialog("Создание дочерней группы", "Введите имя", "Введите комментарий", dr["name"].ToString(), "") == DialogResult.Cancel) return; SaveDataMember(); dr1["name"] = InputBox.Value; dr1["comment"] = InputBox.Value2; dr1["parentid"] = dr[PrimaryKeyName]; AtDataSet.SetFieldValue(dr1, "typ", 0); AtDataSet.SetFieldValue(dr1, "isload", 1); AtDataSet.SetFieldValue(dr1, "guid", Guid.NewGuid()); TableGroup.Rows.Add(dr1); SetNumPos(dr1); SaveToBaseGroup(dr1); RestoreDataMember(); FocusedNode = FindNode(null, PrimaryKeyName, (int)dr1[PrimaryKeyName]); } /// переименовать private void MenuGroupRename_Click(object sender, EventArgs e) { DataRow dr = GetSelectedNode(); #region Вызов событий if (MenuRename_Click != null) { if (!MenuRename_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupRename", MenuGroupRename.Text, dr)) return; } #endregion if (dr == null) return; if (InputBox.ShowDialog("Изменение группы", "Введите новое имя", "Введите новый комментарий", dr["name"].ToString(), dr["comment"].ToString()) == DialogResult.Cancel) return; SaveDataMember(); dr["name"] = InputBox.Value; dr["comment"] = InputBox.Value2; RestoreDataMember(); } /// удалить private void MenuGroupRemove_Click(object sender, EventArgs e) { DataRow dr = GetSelectedNode(); #region Вызов событий if (MenuRemove_Click != null) { if (!MenuRemove_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupRemove", MenuGroupRemove.Text, dr)) return; } #endregion if (dr == null) return; if (RelationGroup == null || RelationGroup.ChildKeyConstraint == null || RelationGroup.ChildKeyConstraint.DeleteRule != Rule.Cascade) { #region Нет связи bool exist = false; foreach (DataRow d in TableGroup.Rows) { if (d.RowState != DataRowState.Deleted) { if (d["parentid"] != DBNull.Value) { if ((int)d["parentid"] == (int)dr[PrimaryKeyName]) { exist = true; break; } } } } if (exist) { MessageBox.Show("Сначало необходимо удалить вложенные группы.", "Удаление группы", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } #endregion } else { #region Есть связь if (dr.GetChildRows(RelationGroup).Length != 0) { DialogResult dir = MessageBox.Show("Группа содержит вложенные подгруппы. Удалить группу вместе с вложениями?", "Удаление группы", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dir == DialogResult.No) return; } #endregion } SaveDataMember(); DataRow[] drs = SetPositionBeforeDelete(dr); // Позиционирование dr.Delete(); RestoreDataMember(); if (drs != null && drs.Length != 0) { TreeListNode nod = FindNode(null, PrimaryKeyName, (int)drs[0][PrimaryKeyName]); FocusedNode = nod; } Focus(); } /// Настроить фильтр void MenuGroupSetupFilter_Click(object sender, EventArgs e) { DataRow dr = GetSelectedNode(); #region Вызов событий if (MenuSetupFilter_Click != null) { if (!MenuSetupFilter_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupSetupFilter", MenuGroupSetupFilter.Text, dr)) return; } #endregion if (dr == null) return; if (Convert.ToInt32(dr["typ"]) == 0) return; DocFilterForm f = new DocFilterForm(dr["filtertext"].ToString(), DocPrimaryKey); if (f.ShowDialog() == DialogResult.OK) { if (f.FilterText == "") dr["_imageindex"] = 2; dr["filtertext"] = f.FilterText; SaveToBaseGroup(dr); LoadFilter(); } } /// Сделать группу основной void MenuGroupSetMain_Click(object sender, EventArgs e) { MoveGroup = GetSelectedNode(); #region Вызов событий if (MenuSetMain_Click != null) { if (!MenuSetMain_Click(MoveGroup)) { MoveGroup = null; return; } } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupSetMain", MenuGroupSetMain.Text, MoveGroup)) return; } #endregion if (MoveGroup != null) MoveElements(null); } /// Переместить вверх void MenuGroupMoveUp_Click(object sender, EventArgs e) { #region Вызов событий if (MenuMoveUp_Click != null) { if (!MenuMoveUp_Click(GetSelectedNode())) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupMoveUp", MenuGroupMoveUp.Text, GetSelectedNode())) return; } #endregion NodeMove(NodeMoveDirection.MoveUp); } /// Переместить вниз void MenuGroupMoveDown_Click(object sender, EventArgs e) { #region Вызов событий if (MenuMoveDown_Click != null) { if (!MenuMoveDown_Click(GetSelectedNode())) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupMoveDown", MenuGroupMoveDown.Text, GetSelectedNode())) return; } #endregion NodeMove(NodeMoveDirection.MoveDown); } /// Переместить группу void MenuGroupMove_Click(object sender, EventArgs e) { MoveGroup = GetSelectedNode(); #region Вызов событий if (MenuMove_Click != null) { if (!MenuMove_Click(MoveGroup)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupMove", MenuGroupMove.Text, MoveGroup)) return; } #endregion if (MoveGroup != null) Cursor = Cursors.Hand; } /// Добавить фильтр void MenuGroupAddFilter_Click(object sender, EventArgs e) { DataRow dr = GetSelectedNode(); #region Вызов событий if (MenuAddFilter_Click != null) { if (!MenuAddFilter_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupAddFilter", MenuGroupAddFilter.Text, dr)) return; } #endregion if (InputBox.ShowDialog("Создание фильтра", "Введите имя", "Введите комментарий", dr["name"].ToString(), "") == DialogResult.Cancel) return; isAddFilter = true; dr = TableGroup.NewRow(); dr[PrimaryKeyName] = dbconn.GetGenId("gen_" + DataMember); dr["name"] = InputBox.Value; dr["comment"] = InputBox.Value2; dr["typ"] = 1; dr["_imageindex"] = 2; if (TableGroup.Columns["isload"] != null) dr["isload"] = 1; DataRow dr_parent = GetSelectedNode(); if (dr_parent != null) dr["parentid"] = dr_parent[PrimaryKeyName]; SaveDataMember(); TableGroup.Rows.Add(dr); SetNumPos(dr); SaveToBaseGroup(dr); RestoreDataMember(); isAddFilter = false; } /// Дублировать группу и вложенную структуру void MenuGroupDublicateStructure_Click(object sender, EventArgs e) { DataRow dr = GetSelectedNode(); #region Вызов событий if (MenuDublicateStructure_Click != null) { if (!MenuDublicateStructure_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupDublicateStructure", MenuGroupDublicateStructure.Text, dr)) return; } #endregion if (dr == null || RelationGroup == null) return; TreeListNode nod = FindNode(null, PrimaryKeyName, (int)dr[PrimaryKeyName]); bool exp = nod.Expanded; this.Refresh(); Cursor = Cursors.WaitCursor; SaveDataMember(); SetNumPos(); DataRow drNew = AtDataSet.DublicateRow(dr, true, RelationGroup.RelationName); db.SaveDatatable2(TableGroup); TableGroup.AcceptChanges(); RestoreDataMember(); saving = true; if (exp == false) { nod = FindNode(null, PrimaryKeyName, (int)dr[PrimaryKeyName]); nod.Expanded = false; } nod = FindNode(null, PrimaryKeyName, (int)drNew[PrimaryKeyName]); nod.Expanded = false; Enabled = true; Focus(); saving = false; FocusedNode = nod; Cursor = Cursors.Default; } /// Дублировать группу, вложенную структуру и данные void MenuGroupDublicateData_Click(object sender, EventArgs e) { #region Вызов событий DataRow dr = GetSelectedNode(); if (MenuDublicateData_Click != null) { if (!MenuDublicateData_Click(dr)) return; } if (MenuItem_Click != null) { if (!MenuItem_Click("MenuGroupDublicateData", MenuGroupDublicateData.Text, dr)) return; } #endregion } /// Клик по любому пункту меню /// Имя пункта меню /// Текст пункта меню /// Выделенная группа void mnu_Click(object sender, EventArgs e) { if (MenuItem_Click != null) MenuItem_Click(((ToolStripItem)sender).Name, ((ToolStripItem)sender).Text, GetSelectedNode()); } #endregion #region Base /// Загрузка групп /// ID пользователя для которого загружаются группы /// ID вида документа группы которого загружаются public virtual void LoadGroupMethod(int idpeople, int iddocappearance) { int idgroup = 0; DataRow dr = GetSelectedNode(); if (dr != null && dr[PrimaryKeyName] != DBNull.Value) idgroup = (int)dr[PrimaryKeyName]; Enabled = false; db.OpenDB(); db.command.CommandText = @"exec f_getdocgroup " + idpeople + ", " + iddocappearance; db.adapter.Fill(TableGroup); if (idgroup != 0) RestorePosition(idgroup); Enabled = true; } public virtual void LoadDocsMethod(int idgroup) { LoadDocsMethod(idgroup, String.Empty); } /// Загрузка документов /// ID группы документов public virtual void LoadDocsMethod(int idgroup, String sqlWhere) { saving = true; db.SaveDatatable2(TableGroup); TableGroup.AcceptChanges(); if (TableDoc != null) { db.SaveDatatable2(TableDoc); TableDoc.Clear(); TableDoc.AcceptChanges(); if (TableGroup.Columns["isload"] != null && GetSelectedNode() != null && GetSelectedNode()["isload"] != DBNull.Value && Convert.ToBoolean(GetSelectedNode()["isload"]) == false) { if (LoadPictures != null) LoadPictures(""); saving = false; return; } } saving = false; db.CloseDB(); if (String.IsNullOrEmpty(sqlWhere)) db.command.CommandText = "select * from view_" + TableDocName + " where deleted is null and " + PrimaryKeyName + " = " + idgroup; else db.command.CommandText = @"select * from view_" + TableDocName + " where deleted is null and " + PrimaryKeyName + " = " + idgroup + " and " + sqlWhere; db.adapter.Fill(TableDoc); if (LoadPictures != null) LoadPictures(""); } /// Загрузка документов public virtual void LoadDocsMethod() { saving = true; DataRow dr = GetSelectedNode(); if (dr == null) return; int idgroup = (int)dr[PrimaryKeyName]; db.SaveDatatable2(TableGroup); TableGroup.AcceptChanges(); if (TableDoc != null) { db.SaveDatatable2(TableDoc); TableDoc.Clear(); TableDoc.AcceptChanges(); if (TableGroup.Columns["isload"] != null && Useful.GetBool(GetSelectedNode()["isload"]) == false) { saving = false; return; } } saving = false; if (Useful.GetInt32(dr["typ"]) != 0) LoadFilter(); else { db.CloseDB(); db.command.CommandText = "select * from view_" + TableDocName + " where deleted is null and " + PrimaryKeyName + " = " + idgroup; db.adapter.Fill(TableDoc); if (LoadPictures != null) LoadPictures(""); } } /// Загрузка документов текущего фильтра public virtual string LoadFilterMethod() { DataRow dr = GetSelectedNode(); if (dr == null || isAddFilter) return ""; if (TableDoc != null) { db.SaveDatatable2(TableDoc); TableDoc.Clear(); TableDoc.AcceptChanges(); } if (dr["filtertext"] == DBNull.Value) return ""; if (TableGroup.Columns["isload"] != null && dr["isload"] != DBNull.Value && Convert.ToBoolean(dr["isload"]) == false) return ""; string str = ""; using (ThreadingStatusImageForm loadForm = new ThreadingStatusImageForm("Идет загрузка данных о документах выбранного фильтра.", "Пожалуйста, подождите...")) { //список ID заказов DataTable dt_temp = new DataTable(); string cmdText = dr["filtertext"].ToString(); while (cmdText.ToLower().Contains("##idpeople")) { int pos = cmdText.ToLower().IndexOf("##idpeople"); if (pos > 0 && pos < cmdText.Length) cmdText = cmdText.Substring(0, pos) + idcurrentpeople + cmdText.Substring(pos + 10); } db.command.CommandText = cmdText; try { db.adapter.Fill(dt_temp); } catch { } if ((//dt_temp.Columns.Count != 1 || (dt_temp.Columns.Count > 0) && dt_temp.Columns[0].ColumnName.ToLower() != DocPrimaryKey) ) { if (Useful.GetInt32(dr["_imageindex"]) != 2) dr["_imageindex"] = 2; return ""; } else if (Useful.GetInt32(dr["_imageindex"]) != 1) dr["_imageindex"] = 1; foreach (DataRow dro in dt_temp.Rows) str += (dro[DocPrimaryKey].ToString() + " "); str.TrimEnd(); db.command.CommandText = "select o.* from view_" + TableDocName + " o, intlist ('" + str + @"') l where o." + DocPrimaryKey + " = l.number"; db.adapter.Fill(TableDoc); bool needSaveLayuot = DeleteTempRows(TableDoc); bool needLoadLayout = false; for (int i = 1; i < dt_temp.Columns.Count; i++) { if (needSaveLayuot) { try { ((AtUserControl)(this.Parent)).SaveLayoutControl(); } catch { } needSaveLayuot = false; } DataColumn tempcol = dt_temp.Columns[i]; DataColumn doccol = TableDoc.Columns.Add("temp_" + tempcol.ColumnName,tempcol.DataType); doccol.Caption = tempcol.ColumnName; foreach (DataRow temprow in dt_temp.Rows) { foreach (DataRow drDoc in TableDoc.Select(DocPrimaryKey + " = " + temprow[DocPrimaryKey].ToString())) { drDoc[doccol.ColumnName] = temprow[tempcol.ColumnName]; } } if (GridView != null) { DevExpress.XtraGrid.Columns.GridColumn gridcol = GridView.Columns.Add(); gridcol.Name = doccol.ColumnName; gridcol.FieldName = doccol.ColumnName; gridcol.Caption = doccol.Caption; } needLoadLayout = true; } TableDoc.AcceptChanges(); if (GridView != null) { if (!needSaveLayuot && needLoadLayout && File.Exists(LayoutGrid.p + "\\" + PrimaryKeyName + "_" + dr[PrimaryKeyName].ToString() + ".xml")) { GridView.RestoreLayoutFromXml(LayoutGrid.p + "\\" + PrimaryKeyName + "_" + dr[PrimaryKeyName].ToString() + ".xml"); ((AtUserControl)(this.Parent)).NeedRestoreLayout = true; ((AtUserControl)(this.Parent)).NeedSaveLayout = false; } else if (!needSaveLayuot && !needLoadLayout) { ((AtUserControl)(this.Parent)).RestoreLayoutControl(); ((AtUserControl)(this.Parent)).NeedRestoreLayout = false; ((AtUserControl)(this.Parent)).NeedSaveLayout = true; } } // Загрузка кртинок if (LoadPictures != null) LoadPictures(str); } return str; } private bool DeleteTempRows(DataTable TableDoc) { bool result = true; foreach (DataColumn col in TableDoc.Clone().Columns) { if (col.ColumnName.Contains("temp_")) { if (GridView != null && oldNode != null && result) { GridView.SaveLayoutToXml(LayoutGrid.p + "\\" + PrimaryKeyName + "_" + oldNode[PrimaryKeyName].ToString() + ".xml"); } result = false; TableDoc.Columns.Remove(col.ColumnName); if (GridView != null && GridView.Columns[col.ColumnName] != null) { GridView.Columns.Remove(GridView.Columns[col.ColumnName]); } } } return result; } /// Cохранение данных в БД public virtual bool SaveToBaseMethod() { saving = true; try { if (!db.SaveDataSet2(ds)) return false; ds.AcceptChanges(); return true; } finally { saving = false; } } /// Cохранение в БД конкретной группы /// Строка группы public virtual void SaveToBaseGroupMethod(DataRow dr) { if (!db.SaveDataRow(dr, false)) return; dr.AcceptChanges(); } /// Востановление позиции /// ID группы public void RestorePosition(int idgroup) { DataRow[] drs = TableGroup.Select(PrimaryKeyName + "=" + idgroup); if (drs.Length == 0) return; //нашли запись, ищем ветку в дереве TreeListNode node = FindNode(null, PrimaryKeyName, idgroup); if (node == null) return; DataRow dr1 = TableGroup.Rows[node.Id]; if ((int)dr1[PrimaryKeyName] == idgroup) FocusedNode = node; } #endregion #region Empty Load methods /// Пустой метод загрузки групп /// А поровну что это, всё равно метод пустой :-) /// А поровну что это, всё равно метод пустой :-) public void EmptyLoadGroupMethod(int i, int j) { } /// Пустой метод загрузки документов /// А поровну что это, всё равно метод пустой :-) public void EmptyLoadDocsMethod(int i) { } #endregion } }