Перем мКлючБазыВСпискеПользователяИзКоманднойСтроки;
Перем мМаксЧислоКлавиш;
Перем мТекущийНаборПараметров;
Перем мХранимыеДанные;
Перем мНастройкаФормы;

Функция СохраняемаяНастройкаФормы(выхНаименование, выхИменаСвойств) Экспорт 
	СохранитьНаборПараметров();
	выхИменаСвойств = "";
	Результат = Новый Структура;
	Результат.Вставить("ПоказыватьОсобыйЗапуск", ПоказыватьОсобыйЗапуск);
	Результат.Вставить("СписокНаборовПараметров", СписокНаборовПараметров);
	Возврат Результат;
КонецФункции

Функция СвойстваГлобализуемые() Экспорт
	Результат = Новый Структура;
	Результат.Вставить("БазыПользователяСтрокаПоиска");
	Результат.Вставить("ДополнительныеПараметры");
	Результат.Вставить("ЗапретРегламентныхЗаданий");
	Результат.Вставить("ЗапускОтИмениАдминистратора");
	Результат.Вставить("ИзбранноеСверху");
	Результат.Вставить("КаталогиПоискаПлатформы");
	Результат.Вставить("КаталогПортативныхИнструментов");
	Результат.Вставить("КодРазрешения");
	Результат.Вставить("КодЯзыкаСистемы");
	Результат.Вставить("НаборПараметров");
	Результат.Вставить("ОтключитьАутентификациюОС");
	Результат.Вставить("ОткрытьОбработку");
	Результат.Вставить("ОткрытьПортативныеИнструменты");
	Результат.Вставить("ОчисткаКэшаКлиентСерверныхВызовов");
	Результат.Вставить("ПараметрЗапуска");
	Результат.Вставить("ПодключитьОтладчик");
	Результат.Вставить("ПоказыватьОсобыйЗапуск");
	Результат.Вставить("Пользователь");
	Результат.Вставить("РазделениеДанных");
	Результат.Вставить("РежимЗапуска");
	Результат.Вставить("РежимИнтерфейсаТакси");
	Результат.Вставить("СборкаПлатформы");
	Результат.Вставить("СообщитьКоманднуюСтроку");
	Результат.Вставить("СортировкаПоДате");
	Результат.Вставить("СписокНаборовПараметров");
	Результат.Вставить("ТолькоИзбранное");
	//! ЗаполнитьЗначенияСвойств(ЭтаФорма, Результат)
	Возврат Результат;
КонецФункции

//.
// Параметры:
//   НастройкаФормы - Структура - 
//   ДопПараметры - Структура - 
Процедура ЗагрузитьНастройкуВФорме(НастройкаФормы, ДопПараметры) Экспорт
	мНастройкаФормы = НастройкаФормы;
КонецПроцедуры

Процедура ИзменитьСвернутостьПанельОсобыйЗапускОтложенно() Экспорт
	ИзменитьСвернутостьПанельОсобыйЗапуск(ПоказыватьОсобыйЗапуск);
КонецПроцедуры

//.
// Параметры:
//   ХранимыеДопАтрибуты - см. ХранимыеАтрибуты - 
Процедура ЗагрузитьХранимыеАтрибутыБаз(Знач ХранимыеДопАтрибуты) Экспорт
	Для Каждого СтрокаХранимая Из ХранимыеДопАтрибуты Цикл
		СтрокаБазы = БазыПользователя.Найти(СтрокаХранимая.Идентификатор, "Идентификатор");
		Если СтрокаБазы <> Неопределено Тогда
			ЗаполнитьЗначенияСвойств(СтрокаБазы, СтрокаХранимая);
		КонецЕсли;
	КонецЦикла;
	ОбновитьПодменюКлавишЗапуска();
КонецПроцедуры

Функция ХранимыеАтрибуты() Экспорт
	Результат = БазыПользователя.Выгрузить(, "Идентификатор, " + ирОбщий.СтрСоединитьЛкс(ИменаХранимыхВнеФайлаАтрибутов()));
	Возврат Результат;
КонецФункции

Процедура ПриОткрытии()
	ирКлиент.Форма_ПриОткрытииЛкс(ЭтаФорма);
	СохранитьКопиюСпискаБаз(Истина);
	мКлючБазыВСпискеПользователяИзКоманднойСтроки = ирКэш.КлючБазыВСпискеПользователяИзКоманднойСтрокиЛкс();
	ЭтаФорма.ФайлСписокПользователя = ирОбщий.ИмяФайлаСпискаИнфобазПользователяОСЛкс();
	ЭтаФорма.ФайлСписокОбщийПользователя = ирОбщий.ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс(УказательОбщийПользователя);
	ЭтаФорма.ФайлСписокОбщийВсехПользователей = ирОбщий.ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс(УказательОбщийВсехПользователей);
	ирКлиент.ЗагрузитьНастройкуФормыЛкс(ЭтаФорма, мНастройкаФормы);
	ОбновитьСписокВыбораНаборовПараметров();
	Если ЗначениеЗаполнено(БазыПользователяСтрокаПоиска) Тогда
		ПрименитьФильтрПоПодстрокеБезСохранения();
	КонецЕсли; 
	ОбновитьСписок();
	ЭтотОбъект.ИмяФайлаДопАтрибутов = мПлатформа.ИмяФайлаНастроекКомпьютера(Ложь, "IRInfobaseList.xml");
	ФайлБольшихДанных = ФайлБольшихДанных();
	мХранимыеДанные.ХранимыеАтрибуты = Неопределено;
	Если ФайлБольшихДанных.Существует() Тогда
		ДанныеИзФайла = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлБольшихДанных.ПолноеИмя);
		Если ДанныеИзФайла <> Неопределено Тогда
			ЗаполнитьЗначенияСвойств(мХранимыеДанные, ДанныеИзФайла);
		КонецЕсли;
	КонецЕсли;
	Если мХранимыеДанные.ХранимыеАтрибуты = Неопределено Тогда
		ЗаполнитьЗначенияСвойств(мХранимыеДанные, мНастройкаФормы);
	КонецЕсли;
	Если мХранимыеДанные.РежимыЗапускаОбычногоПриложения <> Неопределено Тогда
		ЗагрузитьХранимыеАтрибутыБаз(мХранимыеДанные.ХранимыеАтрибуты);
	КонецЕсли;
	Если мХранимыеДанные.РежимыЗапускаОбычногоПриложения <> Неопределено Тогда
		Для Каждого СтрокаХранимая Из мХранимыеДанные.РежимыЗапускаОбычногоПриложения Цикл
			СтрокаБазы = БазыПользователя.Найти(СтрокаХранимая.Идентификатор, "Идентификатор");
			Если СтрокаБазы <> Неопределено Тогда
				ЗаполнитьЗначенияСвойств(СтрокаБазы, СтрокаХранимая);
			КонецЕсли;
		КонецЦикла;
		ирКлиент.ТабличноеПолеВосстановитьСостояниеСтрокЛкс(ЭлементыФормы.Папки, мХранимыеДанные.ПапкиСостояние);
		ирКлиент.ТабличноеПолеВосстановитьСостояниеСтрокЛкс(ЭлементыФормы.БазыПользователя, мХранимыеДанные.БазыПользователяСостояние);
	КонецЕсли;
	НастроитьЭлементыФормы();
	ОбновитьКомпоновкуСписка();
	ПодключитьОбработчикОжидания("ИзменитьСвернутостьПанельОсобыйЗапускОтложенно", 0.1, Истина);
	Если НачальноеЗначениеВыбора <> Неопределено Тогда
		СтрокаСписка = БазыПользователя.Найти(НРег(НачальноеЗначениеВыбора), "КлючСтроки");
		Если СтрокаСписка = Неопределено Тогда
			СтрокаСписка = БазыПользователя.Найти(НРег(НачальноеЗначениеВыбора), "НСтрокаСоединения");
		КонецЕсли;
		Если СтрокаСписка <> Неопределено Тогда
			ЭлементыФормы.Папки.ТекущаяСтрока = ПапкаВсе();
			ЭтаФорма.БазыПользователяСтрокаПоиска = "";
			ПрименитьФильтрПоПодстрокеБезСохранения();
			ЭлементыФормы.БазыПользователя.ТекущаяСтрока = СтрокаСписка;
		КонецЕсли;
	КонецЕсли;
	НастроитьЭлементыФормы();
	ирКлиент.ДопСвойстваЭлементаФормыЛкс(ЭтаФорма, ЭлементыФормы.БазыПользователя).МенеджерПоиска = ирКлиент.СоздатьМенеджерПоискаВТабличномПолеЛкс(Новый Структура("ИмяВСписке, СтрокаСоединения"));
КонецПроцедуры

Функция ПапкаВсе() Экспорт
	Результат = Папки.Строки.Найти("<Все>", "Имя");
	Возврат Результат;
КонецФункции

Процедура НастроитьЭлементыФормы() Экспорт
	Для Каждого Колонка Из ЭлементыФормы.БазыПользователя.Колонки Цикл
		Если Ложь
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.Избранное
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.ДатаЗапуска
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.ВерсияПлатформы
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.ИмяВСписке
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.Файловая
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.КлавишаЗапуска
			Или Колонка = ЭлементыФормы.БазыПользователя.Колонки.СтрокаСоединения
		Тогда
			Продолжить;
		КонецЕсли;
		Колонка.Видимость = Не РежимСтартера;
	КонецЦикла;
	ЭлементыФормы.ФайлСписокПользователя.Видимость = Не РежимСтартера;
	ЭлементыФормы.НадписьФайлСписокПользователя.Видимость = Не РежимСтартера;
КонецПроцедуры

Процедура ОбновитьСписок() 
	ХранимыеАтрибуты = ХранимыеАтрибуты();
	ПапкиСостояние = ирКлиент.ТабличноеПолеСостояниеСтрокЛкс(ЭлементыФормы.Папки, "Идентификатор");
	БазыПользователяСостояние = ирКлиент.ТабличноеПолеСостояниеСтрокЛкс(ЭлементыФормы.БазыПользователя, "Идентификатор");
	Если ЭлементыФормы.БазыПользователя.ТекущаяСтрока <> Неопределено Тогда
		ИДТекущейБазы = ЭлементыФормы.БазыПользователя.ТекущаяСтрока.ID;
	КонецЕсли;
	Для Счетчик = 1 По 2 Цикл
		БазыПользователя.Очистить();
		Папки.Строки.Очистить();
		СтрокаПапкиВсе = Папки.Строки.Добавить();
		СтрокаПапкиВсе.Имя = "<Все>";
		СтрокаПапкиВсе.ИмяВСписке = СтрокаПапкиВсе.Имя;
		СтрокаПапкиВсе.Идентификатор = "_";
		СтрокаПапкиПустая = Папки.Строки.Добавить();
		СтрокаПапкиПустая.Имя = "<Пустая>";
		СтрокаПапкиПустая.ИмяВСписке = СтрокаПапкиПустая.Имя;
		ТаблицаБазКлиента = ирОбщий.СписокБазПользователяОСЛкс(, Не РежимСтартера, Истина);
		Для Каждого СтрокаТаблицы Из ТаблицаБазКлиента Цикл
			Если ПустаяСтрока(СтрокаТаблицы.Connect) Тогда
				ПолноеИмяПапки = СтрокаТаблицы.Folder;
				Если ПолноеИмяПапки <> "/" Тогда
					ПолноеИмяПапки = ПолноеИмяПапки + "/";
				КонецЕсли;
				СтрокаПапки = РодительИзИмениПапки(ПолноеИмяПапки + СтрокаТаблицы.ИмяВСписке);
				ЗаполнитьЗначенияСвойств(СтрокаПапки, СтрокаТаблицы,, "ИмяВСписке");
				СтрокаПапки.Идентификатор = СтрокаТаблицы.ID;
				Если ПустаяСтрока(СтрокаПапки.Идентификатор) Тогда
					СтрокаПапки.Идентификатор = Новый УникальныйИдентификатор;
					СтрокаПапки.ID = СтрокаПапки.Идентификатор;
				КонецЕсли;
			Иначе
				СтрокаТЧ = БазыПользователя.Добавить();
				ЗаполнитьЗначенияСвойств(СтрокаТЧ, СтрокаТаблицы);
				СтрокаРежимаЗапуска = РежимыЗапускаПриложения().Найти(НРег(СтрокаТЧ.App), "НВнутр");
				Если СтрокаРежимаЗапуска <> Неопределено Тогда
					СтрокаТЧ.РежимЗапуска = СтрокаРежимаЗапуска.Имя;
				КонецЕсли;
				КаталогДанных = НСтр(СтрокаТЧ.СтрокаСоединения, "file");
				СтрокаТЧ.Файловая = ЗначениеЗаполнено(КаталогДанных);
				СтрокаТЧ.КаталогДанных = КаталогДанных;
				СтрокаТЧ.Кластер = НСтр(СтрокаТЧ.СтрокаСоединения, "srvr");
				СтрокаТЧ.ИмяВКластере = НСтр(СтрокаТЧ.СтрокаСоединения, "ref");
				Если Не РежимСтартера Тогда
					СтрокаТЧ.РазмерФайловойБазыКБ = ирОбщий.ВычислитьРазмерКаталогаЛкс(КаталогДанных) / 1024;
				КонецЕсли;
				Если СтрокаТЧ.Файловая И ЗначениеЗаполнено(СтрокаТЧ.DefaultVersion) Тогда
					СтрокаТЧ.DefaultVersion = "";
					СтрокаТЧ.Изменена = Истина;
				КонецЕсли;
				ОбновитьПредставлениеБазы(СтрокаТЧ);
			КонецЕсли;
		КонецЦикла;
		Если БазыПользователя.Найти(Истина, "Изменена") <> Неопределено Тогда
			ЗаписатьСписокБаз();
		Иначе
			Прервать;
		КонецЕсли;
	КонецЦикла;
	ОбновитьПапкиПоБазам();
	СортироватьПапки();
	Если ИДТекущейБазы <> Неопределено Тогда
		ТекущаяСтрока = БазыПользователя.Найти(ИДТекущейБазы, "ID");
		Если ТекущаяСтрока <> Неопределено Тогда
			ЭлементыФормы.БазыПользователя.ТекущаяСтрока = ТекущаяСтрока;
		КонецЕсли;
	КонецЕсли;
	ЗагрузитьХранимыеАтрибутыБаз(ХранимыеАтрибуты);
	ОбновитьКомпоновкуСписка();
	ирКлиент.ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ЭлементыФормы.Папки);
	ирКлиент.ТабличноеПолеВосстановитьСостояниеСтрокЛкс(ЭлементыФормы.Папки, ПапкиСостояние);
	ирКлиент.ТабличноеПолеВосстановитьСостояниеСтрокЛкс(ЭлементыФормы.БазыПользователя, БазыПользователяСостояние);
КонецПроцедуры

Процедура СортироватьПапки() Экспорт
	Папки.Строки.Сортировать("Имя", Истина);
КонецПроцедуры

Процедура ОбновитьПапкиПоБазам() Экспорт 
	Папки.Колонки.Удалить(Папки.Колонки.ЧислоБаз);
	Папки.Колонки.Добавить("ЧислоБаз", Новый ОписаниеТипов("Число"));
	СтрокаПапкиВсе = ПапкаВсе();
	СтрокаПапкиВсе.ЧислоБаз = БазыПользователя.Количество();
	Для Каждого БазыЭлемент Из БазыПользователя Цикл
		ИмяВСписке = БазыЭлемент.Folder;
		Если ИмяВСписке = "/" Тогда
			СтрокаПапки = Папки.Строки.Найти("<Пустая>", "Имя");
		Иначе
			СтрокаПапки = Папки.Строки.Найти(ИмяВСписке, "ИмяВСписке", Истина);
		КонецЕсли;
		Если СтрокаПапки = Неопределено Тогда
			// Битая ссылка на папку
			СтрокаПапки = РодительИзИмениПапки(ИмяВСписке);
			СтрокаПапки.Идентификатор = Новый УникальныйИдентификатор;
			СтрокаПапки.ID = СтрокаПапки.Идентификатор;
		КонецЕсли;
		СтрокаПапки.ЧислоБаз = СтрокаПапки.ЧислоБаз + 1;
		БазыЭлемент.Папка = СтрокаПапки.Идентификатор;
	КонецЦикла;
КонецПроцедуры

Функция РодительИзИмениПапки(Знач ИмяВСписке) Экспорт
	Родители = ирОбщий.СтрРазделитьЛкс(ИмяВСписке, "/");
	Результат = Папки;
	ТекущееИмяВСписке = "";
	Для Каждого ИмяРодителя Из Родители Цикл
		ТекущееИмяВСписке = ТекущееИмяВСписке + "/" + ИмяРодителя;
		Если ПустаяСтрока(ИмяРодителя) Тогда
			Продолжить;
		КонецЕсли;
		НовыйРезультат = Результат.Строки.Найти(ИмяРодителя, "Имя");
		Если НовыйРезультат = Неопределено Тогда
			НовыйРезультат = Результат.Строки.Добавить();
			НовыйРезультат.Имя = ИмяРодителя;
			ОбновитьПолноеИмяПапки(НовыйРезультат);
		КонецЕсли;
		Результат = НовыйРезультат;
	КонецЦикла;
	Возврат Результат;
КонецФункции

Процедура СписокБазПользователяПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	#Если Сервер И Не Сервер Тогда
		ДанныеСтроки = БазыПользователя.Добавить();
	#КонецЕсли
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
	Если Ложь
		Или (Истина
			И ЗначениеЗаполнено(мКлючБазыВСпискеПользователяИзКоманднойСтроки)
			И ДанныеСтроки.КлючСтроки = НРег(мКлючБазыВСпискеПользователяИзКоманднойСтроки))
		Или (Истина
			И Не ЗначениеЗаполнено(мКлючБазыВСпискеПользователяИзКоманднойСтроки)
			И ДанныеСтроки.НСтрокаСоединения = НРег(СтрокаСоединенияИнформационнойБазы()))
	Тогда
		ОформлениеСтроки.ЦветФона = ирОбщий.ЦветФонаАкцентаЛкс();
	КонецЕсли;
	Если ДанныеСтроки.ФайлСписка <> ФайлСписокПользователя Тогда
		ОформлениеСтроки.ЦветТекста = WebЦвета.ТемноФиолетовый;
	КонецЕсли;
КонецПроцедуры

Процедура ДействияФормыОбновить(Кнопка)
	ОбновитьСписок();
	СборкиПлатформы.Очистить();
КонецПроцедуры

Процедура СписокБазПользователяВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	Если РежимВыбора И ЗначениеЗаполнено(ЭлементыФормы.БазыПользователя.ТекущаяСтрока.Connect) Тогда
		ПоследниеВыбранныеДобавить();
		Закрыть(ЭлементыФормы.БазыПользователя.ТекущаяСтрока);
	ИначеЕсли Колонка = Элемент.Колонки.ВерсияПлатформы Тогда
		РезультатВыбора = ОткрытьВыборВерсииПлатформы(ВыбраннаяСтрока.ВерсияПлатформы, "СборкаПлатформы");
		Если РезультатВыбора <> Неопределено Тогда
			ВыбраннаяСтрока.ВерсияПлатформы = РезультатВыбора.СборкаПлатформы;
			ВыбраннаяСтрока.Изменена = Истина;
			ЗаписатьСписокБаз();
		КонецЕсли;
	ИначеЕсли Ложь
		Или Колонка = Элемент.Колонки.КаталогКэша 
		Или Колонка = Элемент.Колонки.КаталогНастроек 
		Или Колонка = Элемент.Колонки.КаталогДанных
		Или Колонка = Элемент.Колонки.ФайлСписка
	Тогда
		ирКлиент.ОткрытьФайлВПроводникеЛкс(ВыбраннаяСтрока[Колонка.Данные]);
	ИначеЕсли Колонка = Элемент.Колонки.КлавишаЗапуска Тогда
		Если ЗначениеЗаполнено(ВыбраннаяСтрока.КлавишаЗапуска) Тогда
			ВыбраннаяСтрока.КлавишаЗапуска = Неопределено;
		Иначе
			Для Сч=1 По мМаксЧислоКлавиш Цикл
				Если БазыПользователя.Найти(Сч, "КлавишаЗапуска") = Неопределено Тогда
					ВыбраннаяСтрока.КлавишаЗапуска = Сч;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если Сч > мМаксЧислоКлавиш Тогда
				ирОбщий.СообщитьЛкс("Нет свободных клавиш. Смотри подменю ""Клавиши быстрого запуска баз""");
			КонецЕсли;
		КонецЕсли;
		ОбновитьПодменюКлавишЗапуска();
		ЗаписатьСписокБаз();
	ИначеЕсли ЗначениеЗаполнено(ЭлементыФормы.БазыПользователя.ТекущаяСтрока.Connect) Тогда
		ЗапуститьПриложение1С(Ложь);
	КонецЕсли;
КонецПроцедуры

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник);
КонецПроцедуры

Процедура ДействияФормыОчиститьКаталогКэша(Кнопка)
	Для Каждого ВыделеннаяСтрока Из ЭлементыФормы.БазыПользователя.ВыделенныеСтроки Цикл
		ОчиститьКаталогКэшаБазы(ВыделеннаяСтрока);
	КонецЦикла;
КонецПроцедуры

Процедура ОчиститьКаталогКэшаБазы(Знач ВыделеннаяСтрока) Экспорт
	КаталогКэша = ВыделеннаяСтрока.КаталогКэша;
	Если ПустаяСтрока(КаталогКэша) Тогда
		Возврат;
	КонецЕсли;
	Успех = Истина;
	Попытка
		УдалитьФайлы(КаталогКэша);
	Исключение
		Успех = Ложь;
		ирОбщий.СообщитьЛкс("Ошибка очистки кэша базы " + ВыделеннаяСтрока.Представление + ": " + ОписаниеОшибки());
	КонецПопытки;
	Если Успех Тогда
		ВыделеннаяСтрока.РазмерКэшаКБ = 0;
	КонецЕсли;
КонецПроцедуры

Процедура ОткрытьФайлВПроводнике(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ирКлиент.ОткрытьФайлВПроводникеЛкс(Элемент.Значение);
КонецПроцедуры

Процедура ДействияФормыИТС(Кнопка)
	ирКлиент.ОткрытьСсылкуИТСЛкс("https://its.1c.ru/db/v?doc/bookmark/adm/TI000000120"); // общие списки баз
	ирКлиент.ОткрытьСсылкуИТСЛкс("https://its.1c.ru/db/v?doc#bookmark/adm/TI000000368"); // персональный список баз
КонецПроцедуры

Процедура КлсКомандаНажатие(Кнопка)
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
КонецПроцедуры

Процедура СписокБазПользователяПриАктивизацииСтроки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	ирКлиент.Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные);
КонецПроцедуры

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);
КонецПроцедуры

Процедура ДействияФормыЗапуститьКлиентскоеПриложение(Кнопка)
	ЗапуститьПриложение1С(Ложь);
КонецПроцедуры

Процедура ДействияФормыЗапуститьКонфигуратор(Кнопка)
	ЗапуститьПриложение1С(Истина);
КонецПроцедуры

Процедура ЗапуститьПриложение1С(РежимКонфигуратора)
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ИмяВСпискеБазПользователя = ТекущаяСтрока.ИмяВСписке;
	Если РежимКонфигуратора Тогда
		ПараметрЗапускаДляЭлементаСписка = ирОбщий.ПараметрЗапускаПриложенияДляЭлементаСпискаБазЛкс(ИмяВСпискеБазПользователя);
		ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(,,,,, "DESIGNER" + ПараметрЗапускаДляЭлементаСписка);
		Если ТипЗнч(ПроцессОС) = Тип("COMОбъект") Тогда
			мПлатформа.АктивизироватьОкноПроцесса1С8(ПроцессОС.ProcessID);
			ирОбщий.СообщитьЛкс("Активировано окно уже запущенного конфигуратора PID=" + XMLСтрока(ПроцессОС.ProcessID));
			Возврат;
		КонецЕсли;
	КонецЕсли;
	Если ПустаяСтрока(ПодобратьКаталогПлатформы(ТекущаяСтрока, Истина)) Тогда
		ЗапуститьЧерезВерсиюПлатформыСтандартно(РежимКонфигуратора);
		Возврат;
	КонецЕсли;
	Если БазыПользователя.НайтиСтроки(Новый Структура("ИмяВСписке", ИмяВСпискеБазПользователя)).Количество() > 1 Тогда
		ИмяВСпискеБазПользователя = "";
	КонецЕсли;
	ПоследниеВыбранныеДобавить();
	ирКлиент.ЗапуститьПриложение1СЛкс(РежимКонфигуратора,, ТекущаяСтрока.ИмяВСписке,, Ложь, ТекущаяСтрока.Пользователь, ТекущаяСтрока.РежимЗапуска, ТекущаяСтрока.Пароль);
КонецПроцедуры

Процедура ПоследниеВыбранныеДобавить(Знач ТекущиеДанные = Неопределено)
	Если ТекущиеДанные = Неопределено Тогда
		ТекущиеДанные = ЭлементыФормы.БазыПользователя.ТекущиеДанные;
	КонецЕсли;
	ТекущиеДанные.ДатаЗапуска = ТекущаяДата();
	ЗаписатьСписокБаз();
КонецПроцедуры

Функция ОбновитьПредставлениеБазы(Знач ТекущиеДанные = Неопределено) Экспорт
	Если ТекущиеДанные = Неопределено Тогда
		ТекущиеДанные = ЭлементыФормы.БазыПользователя.ТекущиеДанные;
	КонецЕсли;
	Результат = ТекущиеДанные.ИмяВСписке + " [" + ТекущиеДанные.СтрокаСоединения + "]";
	ТекущиеДанные.Представление = Результат;
	Возврат Результат;
КонецФункции

// Обновляет иерархическое имя папки (ИмяВСписке) на основе ее собственного имени (Имя)
// Параметры:
//   ТекущиеДанные -  - 
// Возвращаемое значение:
//    - 
Функция ОбновитьПолноеИмяПапки(Знач ТекущиеДанные = Неопределено) Экспорт
	Если ТекущиеДанные = Неопределено Тогда
		ТекущиеДанные = ЭлементыФормы.Папки.ТекущиеДанные;
	КонецЕсли;
	Если ТекущиеДанные = Папки Тогда
		Возврат "";
	КонецЕсли;
	Результат = ОбновитьПолноеИмяПапки(ирОбщий.РодительСтрокиДереваЛкс(ТекущиеДанные)) + "/" + ТекущиеДанные.Имя;
	ТекущиеДанные.ИмяВСписке = Результат;
	Возврат Результат;
КонецФункции

Процедура ФильтрПоПодстрокеАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, Элемент, Текст);
	ПрименитьФильтрПоПодстрокеБезСохранения();
КонецПроцедуры

Процедура ФильтрПоПодстрокеНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура ФильтрПоПодстрокеПриИзменении(Элемент)
	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	ПрименитьФильтрПоПодстрокеБезСохранения();
КонецПроцедуры

Процедура ПрименитьФильтрПоПодстрокеБезСохранения()
	ЭлементОтбора = ЭлементыФормы.БазыПользователя.ОтборСтрок.Представление;
	ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
	ЭлементОтбора.Значение = БазыПользователяСтрокаПоиска;
	ЭлементОтбора.Использование = ЗначениеЗаполнено(ЭлементОтбора.Значение);
КонецПроцедуры

Процедура ФильтрПоПодстрокеОчистка(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	Элемент.Значение = ""; // Меняем Неопределено на пустую строку
	ПрименитьФильтрПоПодстрокеБезСохранения();
КонецПроцедуры

Процедура РежимСтартераПриИзменении(Элемент)
	Если Не РежимСтартера Тогда
		ОбновитьСписок();
	КонецЕсли;
	НастроитьЭлементыФормы();
КонецПроцедуры

Процедура ЗапуститьСПараметрамиНажатие(Элемент)
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	РежимКонфигуратора = Найти(Элемент.Имя, "Конфигуратор");
	Если Не РежимКонфигуратора И РежимЗапуска = "ВебКлиент" Тогда
		ВебАдрес = НСтр(ТекущаяСтрока.СтрокаСоединения, "ws");
		Если ПустаяСтрока(ВебАдрес) Тогда
			ирОбщий.СообщитьЛкс("Для запуска веб клиента строка соединения базы должна иметь параметр ws");
		Иначе
			ЗапуститьПриложение(ВебАдрес);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	Если Истина
		И Не РежимКонфигуратора
		И ОткрытьПортативныеИнструменты 
		И Не ирКэш.ЛиПортативныйРежимЛкс()
	Тогда
		ФайлПортативный = ИмяБазовогоФайлаПортативного();
		Если Не ФайлПортативный.Существует() Тогда
			ирОбщий.СообщитьЛкс("Отключите флажок ""Открыть портативные инструменты"" или укажите к ним путь в настройках. Скачать можно тут https://devtool1c.ucoz.ru/load/osnovnye/portativnye_instrumenty_razrabotchika_dlja_1s_8_2/1-1-0-6");
			ДействияФормыНастройки();
			ФайлПортативный = ИмяБазовогоФайлаПортативного();
			Если Не ФайлПортативный.Существует() Тогда
				Возврат;
			КонецЕсли;
		КонецЕсли;
		ИмяБазовогоФайлаПортативного = ФайлПортативный.ПолноеИмя;
	КонецЕсли; 
	ПараметрыЗапуска = ирОбщий.ПараметрыЗапускаПриложения1СЛкс(Пользователь, ТекущаяСтрока.Пароль, КодРазрешения, РежимКонфигуратора, РежимЗапуска, Ложь, ОчисткаКэшаКлиентСерверныхВызовов, 
		ДополнительныеПараметры, Ложь,, ОткрытьПортативныеИнструменты, РежимИнтерфейсаТакси, РазделениеДанных, ОтключитьАутентификациюОС, КодЯзыкаСистемы,
		ПараметрЗапуска, ТекущаяСтрока.ИмяВСписке, ИмяБазовогоФайлаПортативного, ЗапретРегламентныхЗаданий, ОткрытьОбработку);
	ОбновитьДоступныеПлатформы();
	КаталогПрограммы = "";
	Тонкий = Не РежимКонфигуратора И РежимЗапуска = "УправляемоеПриложениеТонкий";
	СтрокаСборки = СборкиПлатформы.Найти(СборкаПлатформы, "КлючСборки");
	Если Тонкий И СтрокаСборки = Неопределено Тогда
		СтрокаСборки = ПодобратьСборкуПлатформы(ТекущаяСтрока);
	КонецЕсли;
	Если СтрокаСборки <> Неопределено Тогда
		КаталогПрограммы = СтрокаСборки.Каталог + "bin" + ирОбщий.РазделительПутиКФайлуЛкс();
		ИмяИсполняемогоФайла = ирОбщий.ИмяИсполняемогоФайлаКлиентаПлатформыЛкс(, Тонкий, КаталогПрограммы);
	Иначе
		ИмяИсполняемогоФайла = ирОбщий.ПолноеИмяИсполняемогоФайлаСтартераЛкс();
	КонецЕсли;
	СтрокаЗапуска = """" + ИмяИсполняемогоФайла + """ " + ПараметрыЗапуска;
	Если СообщитьКоманднуюСтроку Тогда
		ирОбщий.СообщитьЛкс(СтрокаЗапуска);
	КонецЕсли;
	ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(СтрокаЗапуска,,, Ложь, ЗапускОтИмениАдминистратора);
	ПоследниеВыбранныеДобавить();
КонецПроцедуры

Процедура ЗапуститьЧерезВерсиюПлатформыСтандартно(Знач РежимКонфигуратора = Ложь)
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	ПараметрыЗапуска = ирОбщий.ПараметрыЗапускаПриложения1СЛкс(ТекущаяСтрока.Пользователь, ТекущаяСтрока.Пароль,, РежимКонфигуратора, ТекущаяСтрока.РежимЗапуска, Ложь,, ТекущаяСтрока.AdditionalParameters, Ложь,
		ТекущаяСтрока.СтрокаСоединения, ,, РазделениеДанных,,,, ТекущаяСтрока.ИмяВСписке);
	ИмяИсполняемогоФайла = ирОбщий.ИмяИсполняемогоФайлаКлиентаПлатформыЛкс(,, ПодобратьКаталогПлатформы(ТекущаяСтрока));
	СтрокаЗапуска = """" + ИмяИсполняемогоФайла + """ " + ПараметрыЗапуска;
	ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(СтрокаЗапуска,,, Ложь);
	ПоследниеВыбранныеДобавить();
КонецПроцедуры 

Функция ПодобратьКаталогПлатформы(СтрокаБазы, Знач ТолькоЕстьВРеестре = Ложь)
	ПодходящаяСборка = ПодобратьСборкуПлатформы(СтрокаБазы, ТолькоЕстьВРеестре);
	Если ПодходящаяСборка = Неопределено Тогда
		Возврат Неопределено;
	Иначе
		Возврат ПодходящаяСборка.Каталог + ирОбщий.РазделительПутиКФайлуЛкс() + "bin" + ирОбщий.РазделительПутиКФайлуЛкс();
	КонецЕсли;
КонецФункции

Функция ПодобратьСборкуПлатформы(СтрокаБазы, Знач ТолькоЕстьВРеестре = Ложь) Экспорт
	ОбновитьДоступныеПлатформы(); 
	Если Истина
		И ЗначениеЗаполнено(СтрокаБазы.DefaultVersion) 
		И (Ложь
			Или ПустаяСтрока(СтрокаБазы.Version)
			Или ирОбщий.СтрНачинаетсяСЛкс(СтрокаБазы.DefaultVersion, СтрокаБазы.Version))
	Тогда
		КлючПоиска = Новый Структура("СборкаПлатформы", СтрокаБазы.DefaultVersion);
		Если ТолькоЕстьВРеестре Тогда
			КлючПоиска.Вставить("ЕстьВРеестре", Истина);
		КонецЕсли;
		ПодходящаяСборка = СборкиПлатформы.НайтиСтроки(КлючПоиска);
		Если ПодходящаяСборка.Количество() Тогда
			ПодходящаяСборка = ПодходящаяСборка[0];
		Иначе
			ПодходящаяСборка = Неопределено;
		КонецЕсли;
	КонецЕсли;
	Если ПодходящаяСборка = Неопределено Тогда
		Если ПустаяСтрока(СтрокаБазы.Version) Тогда
			ПодходящаяСборка = СборкиПлатформы[0];
		Иначе
			Для Каждого СборкиЭлемент Из СборкиПлатформы Цикл
				Если Истина
					И ирОбщий.СтрНачинаетсяСЛкс(СборкиЭлемент.СборкаПлатформы, СтрокаБазы.Version)
					И (Ложь
						Или Не ТолькоЕстьВРеестре
						Или ТолькоЕстьВРеестре И СборкиЭлемент.ЕстьВРеестре)
				Тогда
					ПодходящаяСборка = СборкиЭлемент;
					Прервать;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
	Возврат ПодходящаяСборка;
КонецФункции

Процедура ДополнительныеПараметрыНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура ДополнительныеПараметрыПриИзменении(Элемент)
	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура ПараметрЗапускаНачалоВыбора(Элемент, СтандартнаяОбработка)
	ирКлиент.ПараметрЗапускаНачалоВыбораЛкс(ЭтаФорма, Элемент, СтандартнаяОбработка);
КонецПроцедуры

Процедура СборкаПлатформыНачалоВыбора(Элемент, СтандартнаяОбработка)
	РезультатВыбора = ОткрытьВыборВерсииПлатформы(СборкаПлатформы, "КлючСборки");
	Если РезультатВыбора <> Неопределено Тогда
		ирКлиент.ИнтерактивноЗаписатьВПолеВводаЛкс(Элемент, РезультатВыбора.КлючСборки);
	КонецЕсли;
КонецПроцедуры

Процедура ПриЗакрытии()
	СохранитьХранимыеАтрибуты();
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
КонецПроцедуры

Процедура БазыПользователяПередУдалением(Элемент, Отказ)
	Отказ = Истина; 
	ФормаУдаления = ПолучитьФорму("УдалениеБаз");
	ФормаУдаления.Заголовок = ирОбщий.СтрШаблонЛкс("Удалить выделенные базы (%1 шт)?", ЭлементыФормы.БазыПользователя.ВыделенныеСтроки.Количество());
	Результат = ФормаУдаления.ОткрытьМодально();
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	//КаталогКорзины = ирКэш.КаталогКорзиныЛкс();
	Для Каждого ВыделенныеЭлемент Из Элемент.ВыделенныеСтроки Цикл
		ВыделенныеЭлемент.ПометкаУдаления = Истина;
		Если ФормаУдаления.УдалитьКэшМетаданных Тогда
			ОчиститьКаталогКэшаБазы(ВыделенныеЭлемент);
		КонецЕсли;
		Если ФормаУдаления.УдалитьБазуДанных И ВыделенныеЭлемент.Файловая Тогда
			КаталогДанных = ВыделенныеЭлемент.КаталогДанных;
			Успех = Истина; 
			Попытка
				УдалитьФайлы(КаталогДанных);  
				//ПереместитьФайл(КаталогДанных, КаталогКорзины); // платформа не поддерживает перемещение каталога
			Исключение
				Успех = Ложь;
				ирОбщий.СообщитьЛкс("Ошибка удаления файлов данных базы """ + КаталогДанных + """: " + ОписаниеОшибки());
			КонецПопытки;
			Если Успех Тогда
				ВыделенныеЭлемент.РазмерФайловойБазыКБ = 0;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	ЗаписатьСписокБаз();
	ЭлементыФормы.БазыПользователя.ОбновитьСтроки();
КонецПроцедуры

Процедура ПапкиПередУдалением(Элемент, Отказ)
	Отказ = Истина;
	СтрокаПапки = ЭлементыФормы.Папки.ТекущаяСтрока;
	Если Лев(СтрокаПапки.ИмяВСписке, 1) = "<" Тогда
		Возврат;
	КонецЕсли;
	Если Вопрос("Удалить папку из списка? Ее содержимое переместится в родительскую папку.", РежимДиалогаВопрос.ОКОтмена) <> КодВозвратаДиалога.ОК Тогда
		Возврат;
	КонецЕсли;
	СтрокаПапки.ПометкаУдаления = Истина;
	Для Каждого БазыЭлемент Из БазыПользователя.НайтиСтроки(Новый Структура("Папка", СтрокаПапки.Идентификатор)) Цикл
		Если СтрокаПапки.Родитель = Неопределено Тогда
			БазыЭлемент.Папка = "";
		Иначе
			БазыЭлемент.Папка = СтрокаПапки.Родитель.Идентификатор;
		КонецЕсли;
		БазыЭлемент.Изменена = Истина;
	КонецЦикла;
	Если СтрокаПапки.Родитель <> Неопределено Тогда
		ЭлементыФормы.Папки.ТекущаяСтрока = СтрокаПапки.Родитель;
	КонецЕсли;
	ЗаписатьСписокБаз();
КонецПроцедуры

Процедура ЗаписатьСписокБаз()  
	Для Каждого БазыЭлемент Из БазыПользователя Цикл
		// Мультиметка250121_234547
		БазыЭлемент.Connect = БазыЭлемент.СтрокаСоединения;
		БазыЭлемент.Version = БазыЭлемент.ВерсияПлатформы;
		БазыЭлемент.ID = БазыЭлемент.Идентификатор;
		БазыЭлемент.External = ?(БазыЭлемент.ФайлСписка <> ФайлСписокПользователя, 1, 0); // Если изменили ранее отсутствовавшую в основном списке базу
		Если ЗначениеЗаполнено(БазыЭлемент.Папка) Тогда
			ПапкаИзменена = Ложь;
			ирОбщий.ПрисвоитьЕслиНеРавноЛкс(БазыЭлемент.Folder, Папки.Строки.Найти(БазыЭлемент.Папка, "Идентификатор", Истина).ИмяВСписке, ПапкаИзменена);
			БазыЭлемент.Изменена = БазыЭлемент.Изменена Или ПапкаИзменена;
		Иначе
			БазыЭлемент.Folder = "/"; 
		КонецЕсли;
	КонецЦикла;
	Для Каждого ПапкиЭлемент Из ирОбщий.ВсеСтрокиДереваЗначенийЛкс(Папки) Цикл
		ПапкиЭлемент.ID = ПапкиЭлемент.Идентификатор;
		ПапкиЭлемент.Folder = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ПапкиЭлемент.ИмяВСписке, "/"); 
	КонецЦикла;
	ИменаСтандартныхАтрибутов = ИменаСтандартныхАтрибутов();
	НовыеСтрокиФайла = Новый Массив;
	ЧтениеФайла = Новый ЧтениеТекста;
	СтрокиАтрибутовБазы = Новый Массив;
	ДобавленныеАтрибуты = Новый Структура; 
	Попытка
		ЧтениеФайла.Открыть(ФайлСписокПользователя, КодировкаТекста.UTF8);
		СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
	Исключение
		// Файл существует, но недоступен http://www.hostedredmine.com/issues/882846
		ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
		ирОбщий.СообщитьЛкс("Не удалось записать файл списка баз " + ФайлСписокПользователя + ": " + ОписаниеОшибки);
		Возврат;
	КонецПопытки; 
	НовоеОписаниеБазы = Неопределено;
	НаименованиеБазы = Неопределено; 
	ЭтоКонецФайла = Ложь;
	Пока Истина Цикл
		Если СтрДлина(СтрокаИзФайла) Тогда
			Если Лев(СтрокаИзФайла, 1) = "[" Тогда
				Если Истина
					И НаименованиеБазы <> Неопределено
					И (Ложь
						Или НовоеОписаниеБазы = Неопределено 
						Или Не НовоеОписаниеБазы.ПометкаУдаления)
				Тогда
					Если НовоеОписаниеБазы <> Неопределено Тогда
						Для Каждого ИменаЭлемент Из ИменаСтандартныхАтрибутов Цикл
							Если ДобавленныеАтрибуты.Свойство(ИменаЭлемент) Тогда
								Продолжить;
							КонецЕсли;
							ЗначениеАтрибута = НовоеОписаниеБазы[ИменаЭлемент];
							Если Не ЗначениеЗаполнено(ЗначениеАтрибута) Тогда
								Продолжить;
							КонецЕсли;
							СтрокиАтрибутовБазы.Добавить(ИменаЭлемент + "=" + XMLСтрока(ЗначениеАтрибута));
						КонецЦикла;
					КонецЕсли;
					СтрокиАтрибутовБазы.Добавить(); // Пустая строка для удобства чтения человеком
					СтрокиАтрибутовБазы.Вставить(0, "[" + НаименованиеБазы + "]");
					ирОбщий.ДополнитьМассивЛкс(НовыеСтрокиФайла, СтрокиАтрибутовБазы);
				КонецЕсли;
				Если ЭтоКонецФайла Тогда
					Прервать;
				КонецЕсли;
				НаименованиеБазы = ирОбщий.УдалитьВнешниеСкобкиВыраженияЛкс(СтрокаИзФайла, "[", "]", Ложь);
				СтрокиАтрибутовБазы = Новый Массив;
				ДобавленныеАтрибуты = Новый Структура;
				НовоеОписаниеБазы = Неопределено;
				НовоеОписаниеПапки = Неопределено;
				ИмяКолонки = "";
			Иначе
				ИмяКолонки = ирОбщий.ПервыйФрагментЛкс(СтрокаИзФайла, "=", Ложь);
				ПредставлениеЗначения = СлитьАтрибутБазы(СтрокаИзФайла, СтрокиАтрибутовБазы, НовоеОписаниеБазы, НовоеОписаниеПапки, ДобавленныеАтрибуты);
				Если ирОбщий.СтрокиРавныЛкс(ИмяКолонки, "id") Тогда
					НовоеОписаниеБазы = БазыПользователя.Найти(ПредставлениеЗначения, ИмяКолонки);
					Если НовоеОписаниеБазы <> Неопределено Тогда
						Если НовоеОписаниеБазы.Изменена Тогда
							НаименованиеБазы = НовоеОписаниеБазы.ИмяВСписке;
							НовоеОписаниеБазы.Изменена = Ложь;
							НовыеСтрокиАтрибутов = Новый Массив;
							Для Каждого СтрокаАтрибута Из СтрокиАтрибутовБазы Цикл
								СлитьАтрибутБазы(СтрокаАтрибута, НовыеСтрокиАтрибутов, НовоеОписаниеБазы, НовоеОписаниеПапки, ДобавленныеАтрибуты);
							КонецЦикла;
							СтрокиАтрибутовБазы = НовыеСтрокиАтрибутов
						ИначеЕсли НовоеОписаниеБазы.ПометкаУдаления Тогда
							НаименованиеБазы = Неопределено;
						Иначе
							НовоеОписаниеБазы = Неопределено;
						КонецЕсли;
					КонецЕсли;
					НовоеОписаниеПапки = Папки.Строки.Найти(ПредставлениеЗначения, ИмяКолонки, Истина);
					Если НовоеОписаниеПапки <> Неопределено Тогда
						Если НовоеОписаниеПапки.Изменена Тогда
							НаименованиеБазы = НовоеОписаниеПапки.Имя;
							НовоеОписаниеПапки.Изменена = Ложь;
						ИначеЕсли НовоеОписаниеПапки.ПометкаУдаления Тогда
							НаименованиеБазы = Неопределено;
						Иначе
							НовоеОписаниеПапки = Неопределено;
						КонецЕсли;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку();
		Если СтрокаИзФайла = Неопределено Тогда
			СтрокаИзФайла = "[]";
			ЭтоКонецФайла = Истина;
		КонецЕсли;
	КонецЦикла; 
	ЧтениеФайла.Закрыть(); 
	СериализоватьВыбранныеБазы(БазыПользователя.НайтиСтроки(Новый Структура("Изменена", Истина)), НовыеСтрокиФайла);
	ИзменныеПапки = Папки.Строки.НайтиСтроки(Новый Структура("Изменена", Истина), Истина);
	Для Каждого СтрокаНовойПапки Из ИзменныеПапки Цикл
		СтрокиАтрибутовБазы = Новый Массив;
		СтрокиАтрибутовБазы.Добавить("[" + СтрокаНовойПапки.Имя + "]");
		СтрокиАтрибутовБазы.Добавить("ID=" + СтрокаНовойПапки.Идентификатор);
		СтрокиАтрибутовБазы.Добавить("Folder=" + СтрокаНовойПапки.Folder);
		ирОбщий.ДополнитьМассивЛкс(НовыеСтрокиФайла, СтрокиАтрибутовБазы);
	КонецЦикла;
	Текст = ирОбщий.СтрСоединитьЛкс(НовыеСтрокиФайла, Символы.ПС);
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	
	// Для отладки
	//ТекстовыйДокумент.Прочитать(ФайлСписокПользователя);
	//ирКлиент.Сравнить2ЗначенияВФормеЛкс(ТекстовыйДокумент, Текст);
	//Возврат;
	
	ТекстовыйДокумент.УстановитьТекст(Текст);
	ТекстовыйДокумент.Записать(ФайлСписокПользователя); 
	ирОбщий.УстановитьСвойствоВКоллекцииЛкс(БазыПользователя, "Изменена", Ложь);
	ирОбщий.УстановитьСвойствоВКоллекцииЛкс(ИзменныеПапки, "Изменена", Ложь);
	ирОбщий.УдалитьСтрокиТаблицыИлиДереваПоЗначениюЛкс(БазыПользователя, "ПометкаУдаления", Истина);
	ирОбщий.УдалитьСтрокиТаблицыИлиДереваПоЗначениюЛкс(Папки, "ПометкаУдаления", Истина);
	ирКлиент.СохранитьНастройкуФормыЛкс(ЭтаФорма);
	СохранитьХранимыеАтрибуты();
	ОбновитьПапкиПоБазам();
	//ОбновитьКомпоновкуСписка(); // Часто вредно сортировать сразу https://devtool1c.ucoz.ru/forum/2-2812-1
КонецПроцедуры 

// Вынес отдельно чтобы не замедлять чтение/запись файла общих глобальных настроек
Процедура СохранитьХранимыеАтрибуты() Экспорт
	мХранимыеДанные.ХранимыеАтрибуты = ХранимыеАтрибуты();
	мХранимыеДанные.РежимыЗапускаОбычногоПриложения = БазыПользователя.Выгрузить(Новый Структура("РежимЗапуска", "ОбычноеПриложение"), "Идентификатор, РежимЗапуска");
	мХранимыеДанные.БазыПользователяСостояние = ирКлиент.ТабличноеПолеСостояниеСтрокЛкс(ЭлементыФормы.БазыПользователя, "Идентификатор");
	мХранимыеДанные.ПапкиСостояние = ирКлиент.ТабличноеПолеСостояниеСтрокЛкс(ЭлементыФормы.Папки, "Идентификатор");
	ирОбщий.СохранитьЗначениеВФайлЛкс(мХранимыеДанные, ФайлБольшихДанных().ПолноеИмя);
КонецПроцедуры 

Функция ФайлБольшихДанных() Экспорт
	Возврат Новый Файл(ИмяФайлаДопАтрибутов);
КонецФункции 

//.
// Возвращаемое значение:
//   Массив - 
Функция ИменаСтандартныхАтрибутов() Экспорт
	ИменаСтандартныхАтрибутов = Новый Массив;
	Для Каждого РеквизитыЭлемент Из Метаданные().ТабличныеЧасти.БазыПользователя.Реквизиты Цикл
		Если Не Найти(ирОбщий.РусскиеБуквыЛкс(), НРег(Лев(РеквизитыЭлемент.Имя, 1))) Тогда
			ИменаСтандартныхАтрибутов.Добавить(РеквизитыЭлемент.Имя);
		КонецЕсли;
	КонецЦикла;
	Возврат ИменаСтандартныхАтрибутов;
КонецФункции 

//.
// Параметры:
//   СтрокиВыбранныхБаз - Массив - 
//   НовыеСтрокиФайла - Массив, Неопределено - 
// Возвращаемое значение:
//   Массив - 
Функция СериализоватьВыбранныеБазы(знач СтрокиВыбранныхБаз, Знач НовыеСтрокиФайла = Неопределено) Экспорт
	Если НовыеСтрокиФайла = Неопределено Тогда
		НовыеСтрокиФайла = Новый Массив;
	КонецЕсли;
	ИменаСтандартныхАтрибутов = ИменаСтандартныхАтрибутов();
	Для Каждого СтрокаНовойБазы Из СтрокиВыбранныхБаз Цикл
		СтрокиАтрибутовБазы = Новый Массив;
		СтрокиАтрибутовБазы.Добавить("[" + СтрокаНовойБазы.ИмяВСписке + "]");
		Для Каждого ИменаЭлемент Из ИменаСтандартныхАтрибутов Цикл
			ЗначениеАтрибута = СтрокаНовойБазы[ИменаЭлемент];
			Если Не ЗначениеЗаполнено(ЗначениеАтрибута) Тогда
				Продолжить;
			КонецЕсли;
			СтрокиАтрибутовБазы.Добавить(ИменаЭлемент + "=" + XMLСтрока(ЗначениеАтрибута));
		КонецЦикла;
		ирОбщий.ДополнитьМассивЛкс(НовыеСтрокиФайла, СтрокиАтрибутовБазы);
	КонецЦикла;
	Возврат НовыеСтрокиФайла;
КонецФункции 

Функция СлитьАтрибутБазы(Знач СтрокаИзФайла, Знач СтрокиБазы, Знач НовоеОписаниеБазы, Знач НовоеОписаниеПапки, Знач ДобавленныеАтрибуты) Экспорт
	ИмяКолонки = ирОбщий.ПервыйФрагментЛкс(СтрокаИзФайла, "=", Ложь);
	Если ЗначениеЗаполнено(ИмяКолонки) Тогда
		ДобавленныеАтрибуты.Вставить(ИмяКолонки);
		ПредставлениеЗначения = ирОбщий.ТекстБезПервогоФрагментаЛкс(СтрокаИзФайла, "=");
		Если НовоеОписаниеБазы <> Неопределено Тогда
			Если Метаданные().ТабличныеЧасти.БазыПользователя.Реквизиты.Найти(ИмяКолонки) <> Неопределено Тогда
				ПредставлениеЗначения = XMLСтрока(НовоеОписаниеБазы[ИмяКолонки]);
			КонецЕсли;
		ИначеЕсли НовоеОписаниеПапки <> Неопределено Тогда
			Если Папки.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда
				ПредставлениеЗначения = XMLСтрока(НовоеОписаниеПапки[ИмяКолонки]);
			КонецЕсли;
		КонецЕсли;
		СтрокиБазы.Добавить(ИмяКолонки + "=" + ПредставлениеЗначения);
	КонецЕсли;
	Возврат ПредставлениеЗначения;
КонецФункции 

Функция ИменаХранимыхВнеФайлаАтрибутов()
	Результат = Новый Массив;
	Результат.Добавить("Избранное");
	Результат.Добавить("ДатаЗапуска");
	Результат.Добавить("Пользователь");
	Результат.Добавить("КлавишаЗапуска");
	Результат.Добавить("Пароль");
	Возврат Результат;
КонецФункции

Процедура ПапкиПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	Если НоваяСтрока Тогда
		Элемент.ТекущаяСтрока.Идентификатор = Новый УникальныйИдентификатор;
		ОбновитьИмяПапки();
		ПапкиПриАктивизацииСтроки();
	КонецЕсли;
КонецПроцедуры

Процедура БазыПользователяПриИзмененииФлажка(Элемент, Колонка)
	ирКлиент.ТабличноеПолеПриИзмененииФлажкаЛкс(ЭтаФорма, Элемент, Колонка);
КонецПроцедуры
               
Процедура БазыПользователяИзбранноеПриИзменении(Элемент)
	ирКлиент.СохранитьНастройкуФормыЛкс(ЭтаФорма);
КонецПроцедуры 

Процедура БазыПользователяНаименованиеПриИзменении(Элемент)
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	Если ПустаяСтрока(Элемент.Значение) Тогда
		Элемент.Значение = ТекущаяСтрока.СтрокаСоединения;
	КонецЕсли;
	Элемент.Значение = ирОбщий.АвтоУникальноеИмяВКоллекцииЛкс(БазыПользователя, ТекущаяСтрока, "ИмяВСписке", Ложь);
	ТекущаяСтрока.Изменена = Истина;
	ОбновитьПредставлениеБазы(ТекущаяСтрока);
	ПодключитьОбработчикОжидания("ЗаписатьСписокБаз", 0.1, Истина);
КонецПроцедуры

Процедура БазыПользователяСтрокаСоединенияПриИзменении(Элемент)
	ЭлементыФормы.БазыПользователя.ТекущиеДанные.Изменена = Истина;
	ПодключитьОбработчикОжидания("ЗаписатьСписокБаз", 0.1, Истина);
КонецПроцедуры

Процедура БазыПользователяВерсияПлатформыПриИзменении(Элемент)
	ЭлементыФормы.БазыПользователя.ТекущиеДанные.Изменена = Истина;
	ПодключитьОбработчикОжидания("ЗаписатьСписокБаз", 0.1, Истина);
КонецПроцедуры

Процедура ПапкиПриАктивизацииСтроки(Элемент = Неопределено)
	ЭлементОтбора = ЭлементыФормы.БазыПользователя.ОтборСтрок.Папка;
	Если ЭлементыФормы.Папки.ТекущаяСтрока.ИмяВСписке = "<Все>" Тогда
		ЭлементОтбора.Использование = Ложь;
	Иначе
		ЭлементОтбора.Установить(ЭлементыФормы.Папки.ТекущаяСтрока.Идентификатор);
	КонецЕсли; 
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры 

Процедура ОбновитьКомпоновкуСписка(Знач ВключитьПоДате = Ложь)
	СтрокаСортировки = Новый Массив;
	Если ИзбранноеСверху Тогда
		СтрокаСортировки.Добавить("Избранное Убыв");
	КонецЕсли;
	Если СортировкаПоДате Тогда
		СтрокаСортировки.Добавить("ДатаЗапуска Убыв");
	КонецЕсли;
	СтрокаСортировки.Добавить("Представление");
	БазыПользователя.Сортировать(ирОбщий.СтрСоединитьЛкс(СтрокаСортировки));
	Если СортировкаПоДате И ВключитьПоДате Тогда
		ЭлементыФормы.Папки.ТекущаяСтрока = ПапкаВсе();
		Если ЭлементыФормы.БазыПользователя.ТекущаяСтрока <> БазыПользователя[0] Тогда
			Ответ = Вопрос("Перейти в начало?", РежимДиалогаВопрос.ДаНет);
			Если Ответ = КодВозвратаДиалога.Да Тогда
				ЭлементыФормы.БазыПользователя.ТекущаяСтрока = БазыПользователя[0]; 
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	ЭлементыФормы.БазыПользователя.ОтборСтрок.Избранное.Использование = ТолькоИзбранное;
КонецПроцедуры

Процедура СортировкаПоДатеПриИзменении(Элемент)
	ОбновитьКомпоновкуСписка(Истина);
КонецПроцедуры

Процедура ТолькоИзбранноеПриИзменении(Элемент)
	Если ТолькоИзбранное Тогда
		ЭлементыФормы.БазыПользователя.ОтборСтрок.Папка.Использование = Ложь;
	КонецЕсли;
	ОбновитьКомпоновкуСписка();
КонецПроцедуры

Процедура ОбновлениеОтображения()
	ЭтаФорма.ТолькоИзбранное = ЭлементыФормы.БазыПользователя.ОтборСтрок.Избранное.Использование;
	Если Не ЭлементыФормы.БазыПользователя.ОтборСтрок.Папка.Использование Тогда
		ЭлементыФормы.Папки.ТекущаяСтрока = ПапкаВсе();
	КонецЕсли;
КонецПроцедуры

Процедура БазыПользователяПередНачаломДобавления(Элемент, Отказ, Копирование)
	Отказ = Истина;
	ФормаЭлемента = ПолучитьФорму("Элемент", Элемент);
	Если Копирование Тогда
		ЗагрузитьАтрибутыБазыВРедактор(ФормаЭлемента);
		ФормаЭлемента.Идентификатор = "";
	КонецЕсли;
	Если ЗначениеЗаполнено(ЭлементыФормы.Папки.ТекущаяСтрока.Идентификатор) Тогда
		ИмяВСписке = ЭлементыФормы.Папки.ТекущаяСтрока.ИмяВСписке;
		Если Лев(ИмяВСписке, 1) <> "<" Тогда
			ФормаЭлемента.ПапкаИмя = ИмяВСписке;
			ФормаЭлемента.ПапкаИдентификатор = ЭлементыФормы.Папки.ТекущаяСтрока.Идентификатор;
		КонецЕсли;
	КонецЕсли;
	ФормаЭлемента.Открыть();
КонецПроцедуры

Процедура БазыПользователяПередНачаломИзменения(Элемент, Отказ)
	Если Ложь
		Или ЭлементыФормы.БазыПользователя.ТекущаяКолонка = ЭлементыФормы.БазыПользователя.Колонки.ИмяВСписке 
		Или ЭлементыФормы.БазыПользователя.ТекущаяКолонка = ЭлементыФормы.БазыПользователя.Колонки.Избранное
	Тогда
		Возврат;
	КонецЕсли;
	Отказ = Истина;
	РедактироватьБазу();
КонецПроцедуры

Процедура РедактироватьБазу() Экспорт
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	ФормаЭлемента = ПолучитьФорму("Элемент", ЭлементыФормы.БазыПользователя, ТекущаяСтрока.Идентификатор);
	ФормаЭлемента.ТолькоПросмотр = ТекущаяСтрока.ФайлСписка <> ФайлСписокПользователя;
	ЗагрузитьАтрибутыБазыВРедактор(ФормаЭлемента);
	ФормаЭлемента.Открыть();
КонецПроцедуры

Процедура ЗагрузитьАтрибутыБазыВРедактор(Знач ФормаЭлемента) Экспорт
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	ЗаполнитьЗначенияСвойств(ФормаЭлемента, ТекущаяСтрока);
	ФормаЭлемента.Разрядность = ТекущаяСтрока.AppArch;
	ФормаЭлемента.ДополнительныеПараметры = ТекущаяСтрока.AdditionalParameters;
	ФормаЭлемента.ВерсияПлатформы = ТекущаяСтрока.ВерсияПлатформы;
	ФормаЭлемента.ОтключитьАутентификациюОС = ТекущаяСтрока.WA = 0; 
	ФормаЭлемента.ПапкаИдентификатор = ТекущаяСтрока.Папка;
	ФормаЭлемента.КаталогКэша = ТекущаяСтрока.КаталогКэша;
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	СтрокаПапки = Папки.Строки.Найти(ТекущаяСтрока.Папка, "Идентификатор", Истина);
	Если СтрокаПапки <> Неопределено Тогда
		ФормаЭлемента.ПапкаИмя = СтрокаПапки.ИмяВСписке;
	КонецЕсли;
КонецПроцедуры

Процедура БазыПользователяОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	//! ВыбранноеЗначение = ПолучитьФорму("Элемент", Элемент); 
	Если ПустаяСтрока(ВыбранноеЗначение.Идентификатор) Тогда
		ВыбранноеЗначение.Идентификатор = Новый УникальныйИдентификатор;
	КонецЕсли;
	СтрокаБазы = БазыПользователя.Найти(ВыбранноеЗначение.Идентификатор, "Идентификатор");
	Если СтрокаБазы = Неопределено Тогда
		СтрокаБазы = БазыПользователя.Добавить();
	КонецЕсли;
	ЗаполнитьЗначенияСвойств(СтрокаБазы, ВыбранноеЗначение);
	СтрокаБазы.AppArch = ?(ВыбранноеЗначение.Разрядность = "Auto", "", ВыбранноеЗначение.Разрядность);
	СтрокаБазы.WA = ?(ВыбранноеЗначение.ОтключитьАутентификациюОС, 0, 1);
	СтрокаБазы.Папка = ВыбранноеЗначение.ПапкаИдентификатор;
	СтрокаБазы.AdditionalParameters = ВыбранноеЗначение.ДополнительныеПараметры;
	РежимаЗапускаВнутр = "";
	СтрокаРежимаЗапуска = РежимыЗапускаПриложения().Найти(ВыбранноеЗначение.РежимЗапуска, "Имя");
	Если СтрокаРежимаЗапуска <> Неопределено Тогда
		РежимаЗапускаВнутр = СтрокаРежимаЗапуска.Внутр;
	КонецЕсли;
	СтрокаБазы.App = ?(СтрокаБазы.РежимЗапуска = "Авто", "", РежимаЗапускаВнутр);
	Если ЗначениеЗаполнено(ВыбранноеЗначение.ПапкаИдентификатор) Тогда
		СтрокаПапки = Папки.Строки.Найти(ВыбранноеЗначение.ПапкаИдентификатор, "Идентификатор", Истина);
		Если СтрокаПапки <> Неопределено Тогда
			СтрокаБазы.Папка = СтрокаПапки.Идентификатор; 
		КонецЕсли;
	КонецЕсли;
	СтрокаБазы.ФайлСписка = ФайлСписокПользователя;
	СтрокаБазы.Изменена = Истина;
	СтрокаБазы.ДатаЗапуска = ТекущаяДата();
	ЭлементыФормы.БазыПользователя.ТекущаяСтрока = СтрокаБазы;
	ОбновитьПредставлениеБазы(СтрокаБазы);
	ПоследниеВыбранныеДобавить(СтрокаБазы);
	ЗаписатьСписокБаз();
КонецПроцедуры

Процедура ПапкиПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)
	СтандартнаяОбработка = Ложь;
	ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.Перемещение;
КонецПроцедуры

Процедура ПапкиПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)
	Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив") Тогда
		СтандартнаяОбработка = Ложь;
		Для Каждого СтрокаБазы Из ПараметрыПеретаскивания.Значение Цикл // СтрокаТаблицыЗначений
			Если ирОбщий.ЛиСтрокаТабличнойЧастиЛкс(СтрокаБазы) Тогда
				//! СтрокаБазы = 0 // см. БазыПользователя[0]
				СтрокаБазы.Изменена = Истина;
				Если Строка = Неопределено Тогда
					СтрокаБазы.Папка = "";
				Иначе
					СтрокаБазы.Папка = Строка.Идентификатор;
				КонецЕсли;
			ИначеЕсли ирОбщий.ЛиКолонкиТаблицСовпадаютЛкс(СтрокаБазы.Владелец(), Папки) Тогда
				//! СтрокаБазы = 0 // см. Папки.Строки[0]
				Если Ложь
					Или Строка = Неопределено
					Или Лев(Строка.Имя, 1) = "<"
				Тогда           
					НоваяСтрока = Папки.Строки.Добавить();
				Иначе
					НоваяСтрока = Строка.Строки.Добавить();
				КонецЕсли;
				ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаБазы);
				НоваяСтрока.Изменена = Истина;
				ирОбщий.РодительСтрокиДереваЛкс(СтрокаБазы).Строки.Удалить(СтрокаБазы);
				ОбновитьПолноеИмяПапки(НоваяСтрока);
				Элемент.ТекущаяСтрока = НоваяСтрока;
			КонецЕсли;
		КонецЦикла;
		СортироватьПапки();
		ЭлементыФормы.БазыПользователя.ОбновитьСтроки();
		ЗаписатьСписокБаз();
	КонецЕсли;
КонецПроцедуры

Процедура ДействияФормыНастройки(Кнопка = Неопределено)
	ФормаНастроек = ПолучитьФорму("Настройки", ЭтаФорма);
	ФормаНастроек.ОткрытьМодально();
	Если ФормаНастроек.Модифицированность Тогда
		СборкиПлатформы.Очистить();
	КонецЕсли;
	ирКлиент.СохранитьНастройкуФормыЛкс(ЭтаФорма);
КонецПроцедуры

Процедура ДействияФормыПрофайлыБазы(Кнопка)
	ТекущаяСтрока = ЭлементыФормы.БазыПользователя.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;  
	Форма = ирКлиент.ПолучитьФормуЛкс("Обработка.ирУправлениеПрофайлами1С.Форма");
	Форма.ПараметрСтрокаСпискаБаз = ТекущаяСтрока;
	Форма.Открыть();
КонецПроцедуры

Процедура ДействияФормыИзменить(Кнопка)
	Если ЭлементыФормы.БазыПользователя.ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	РедактироватьБазу();
КонецПроцедуры

Процедура ДействияФормыОчиститьПривязкуКлавиш(Кнопка)
	
	ирОбщий.ОчиститьКолонкиТаблицыЛкс(БазыПользователя, "КлавишаЗапуска");
	ОбновитьПодменюКлавишЗапуска();
	ЗаписатьСписокБаз();
	
КонецПроцедуры 

Процедура ОбновитьПодменюКлавишЗапуска()
	Для Сч=1 По мМаксЧислоКлавиш Цикл
		СтрокаБазы = БазыПользователя.Найти(Сч, "КлавишаЗапуска");
		КнопкаПанели = ЭлементыФормы.ДействияФормы.Кнопки.КлавишиЗапуска.Кнопки["ЗапуститьБазу" + Сч];
		Если СтрокаБазы = Неопределено Тогда
			ПредставлениеБазы = "Нет";
		Иначе
			ПредставлениеБазы = СтрокаБазы.Представление;
		КонецЕсли;
		ирОбщий.ОбновитьТекстПослеМаркераЛкс(КнопкаПанели.Текст,, ПредставлениеБазы, ": ");
	КонецЦикла;
КонецПроцедуры

Процедура ЗапуститьБазуКлавишей(Кнопка)
	СтрокаБазы = БазыПользователя.Найти(Число(Прав(Кнопка.Имя, 1)), "КлавишаЗапуска");
	Если СтрокаБазы <> Неопределено Тогда
		ЭлементыФормы.БазыПользователя.ТекущаяСтрока = СтрокаБазы;
		ЗапуститьПриложение1С(Ложь);
	КонецЕсли;
КонецПроцедуры

Процедура НаборПараметровПриИзменении(Элемент)
	СохранитьНаборПараметров();
	мТекущийНаборПараметров = ирОбщий.НайтиЭлементКоллекцииЛкс(СписокНаборовПараметров, "Представление", Элемент.Значение);
	Если мТекущийНаборПараметров = Неопределено Тогда
		мТекущийНаборПараметров = СписокНаборовПараметров.Добавить();
		мТекущийНаборПараметров.Представление = Элемент.Значение;
		СохранитьНаборПараметров();
		ОбновитьСписокВыбораНаборовПараметров();
	Иначе
		ЗаполнитьЗначенияСвойств(ЭтаФорма, мТекущийНаборПараметров.Значение);
	КонецЕсли;
КонецПроцедуры

Процедура СохранитьНаборПараметров() Экспорт
	Если мТекущийНаборПараметров <> Неопределено Тогда
		мТекущийНаборПараметров.Значение = Новый Структура(ИменаПараметровРазовогоЗапуска());
		ЗаполнитьЗначенияСвойств(мТекущийНаборПараметров.Значение, ЭтаФорма);
	КонецЕсли;
КонецПроцедуры

Функция ИменаПараметровРазовогоЗапуска()
	Возврат "ОткрытьОбработку, СборкаПлатформы, РежимЗапуска, ОчисткаКэшаКлиентСерверныхВызовов, КодРазрешения, ПодключитьОтладчик, СообщитьКоманднуюСтроку, ОткрытьПортативныеИнструменты, РежимИнтерфейсаТакси, РазделениеДанных, ЗапускОтИмениАдминистратора, КодЯзыкаСистемы, ПараметрЗапуска, ДополнительныеПараметры, ОтключитьАутентификациюОС, Пользователь, ЗапретРегламентныхЗаданий";
КонецФункции

Процедура НаборПараметровНачалоВыбора(Элемент, СтандартнаяОбработка)
	//Если ирКлиент.РедактироватьСписокЗначенийЛкс(СписокНаборовПараметров,, "Наборы параметров запуска") Тогда
	ФормаСохраненияНастройки = мПлатформа.ПолучитьФорму("ВыборНастройкиДляЗагрузки");
	НачальныйИндекс = 0;
	Если мТекущийНаборПараметров <> Неопределено Тогда
		НачальныйИндекс = СписокНаборовПараметров.Индекс(мТекущийНаборПараметров);
	КонецЕсли;
	ФормаСохраненияНастройки.НачальноеЗначениеВыбора = НачальныйИндекс;
	ФормаСохраненияНастройки.СписокНастроек = ирОбщий.ТаблицаЗначенийИзКоллекцииЛкс(СписокНаборовПараметров);
	ВыбранныйНаборПараметров = ФормаСохраненияНастройки.ОткрытьМодально();    
	СписокНаборовПараметров.Очистить();
	Для Каждого СтрокаТаблицы Из ФормаСохраненияНастройки.СписокНастроек Цикл
		ЗаполнитьЗначенияСвойств(СписокНаборовПараметров.Добавить(), СтрокаТаблицы);
	КонецЦикла;
	ОбновитьСписокВыбораНаборовПараметров();
	Если ВыбранныйНаборПараметров <> Неопределено Тогда
		Элемент.Значение = ВыбранныйНаборПараметров.Представление;
		ирКлиент.ИнтерактивноЗаписатьВПолеВводаЛкс(Элемент, Элемент.Значение);
	КонецЕсли;
КонецПроцедуры

Процедура ОбновитьСписокВыбораНаборовПараметров() Экспорт
	Если СписокНаборовПараметров.Количество() = 0 Тогда
		НаборПараметровОчистка(ЭлементыФормы.НаборПараметров);
	КонецЕсли;
	СписокНаборовПараметров.СортироватьПоПредставлению();
	ЭлементыФормы.НаборПараметров.СписокВыбора.ЗагрузитьЗначения(ирОбщий.ВыгрузитьСвойствоЛкс(СписокНаборовПараметров));
КонецПроцедуры

Процедура НаборПараметровОчистка(Элемент, СтандартнаяОбработка = Истина)
	СтандартнаяОбработка = Ложь;
	мТекущийНаборПараметров = Неопределено;
	Элемент.Значение = "<Основной>";
	НаборПараметровПриИзменении(Элемент);
КонецПроцедуры

Процедура ОткрытьОбработкуНачалоВыбора(Элемент, СтандартнаяОбработка)
	Результат = ирКлиент.ВыбратьФайлЛкс(, "epf", "Внешняя обработка", Элемент.Значение);
	Если Результат <> Неопределено Тогда
		ирКлиент.ИнтерактивноЗаписатьВПолеВводаЛкс(Элемент, Результат);
	КонецЕсли;
КонецПроцедуры

Процедура ОткрытьОбработкуОткрытие(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ирКлиент.ОткрытьФайлВПроводникеЛкс(Элемент.Значение);
КонецПроцедуры

Процедура РежимЗапускаОчистка(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	Элемент.Значение = "Авто";
КонецПроцедуры

Процедура ДополнительныеПараметрыНачалоВыбора(Элемент, СтандартнаяОбработка)
	ирКлиент.ПолеВводаРасширенногоЗначения_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка);
КонецПроцедуры

Процедура ИзменитьСвернутостьПанельОсобыйЗапуск(Знач Видимость, Знач Запоминать = Истина)
	
	ирКлиент.ИзменитьСвернутостьЛкс(ЭтаФорма, Видимость, ЭлементыФормы.ПанельОсобыйЗапуск, ЭтаФорма.ЭлементыФормы.вРазделительСписокОсобыйЗапуск, ЭтаФорма.Панель, "право",, Ложь);
	ЭлементыФормы.ДействияФормы.Кнопки.СверткаОсобыйЗапуск.Пометка = Видимость;
	Если Запоминать Тогда
		ЭтаФорма.ПоказыватьОсобыйЗапуск = Видимость;
	КонецЕсли;
	
КонецПроцедуры

Процедура ДействияФормыСверткаОсобыйЗапуск(Кнопка)
	ИзменитьСвернутостьПанельОсобыйЗапуск(Не ПоказыватьОсобыйЗапуск);
КонецПроцедуры

Процедура ИзбранноеСверхуПриИзменении(Элемент)
	ОбновитьКомпоновкуСписка();
КонецПроцедуры

Процедура ПапкиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
КонецПроцедуры

Процедура ПапкиПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель)
	
	Если Лев(Родитель.Имя, 1) = "<" Тогда
		Отказ = Истина;
		СтрокаДерева = Папки.Строки.Добавить();
		СтрокаДерева.Идентификатор = Новый УникальныйИдентификатор;
		СтрокаДерева.ID = СтрокаДерева.Идентификатор;
		Элемент.ТекущаяСтрока = СтрокаДерева;
		ОбновитьИмяПапки();
		Элемент.ИзменитьСтроку();
	КонецЕсли;
	
КонецПроцедуры

Процедура ПапкиПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
	Если ОтменаРедактирования Тогда
		Возврат;
	КонецЕсли;
	ОбновитьИмяПапки();
КонецПроцедуры

Процедура ОбновитьИмяПапки() Экспорт
	ТекущиеДанные = ЭлементыФормы.Папки.ТекущиеДанные;
	ТекущиеДанные.Имя = ирОбщий.АвтоУникальноеИмяВКоллекцииЛкс(ирОбщий.РодительСтрокиДереваЛкс(ТекущиеДанные).Строки, ТекущиеДанные,,, "Папка");
	ТекущиеДанные.Изменена = Истина;
	ОбновитьПолноеИмяПапки();
	ПодключитьОбработчикОжидания("ЗаписатьСписокБаз", 0.1, Истина);
КонецПроцедуры

Процедура ДействияФормыСохранитьВНовыйСписокБаз(Кнопка)
	ИмяФайла = ирКлиент.ВыбратьФайлЛкс(Ложь, "v8i", "Список баз 1С");
	Если ПустаяСтрока(ИмяФайла) Тогда
		Возврат;
	КонецЕсли;
	Массив = СериализоватьВыбранныеБазы(ЭлементыФормы.БазыПользователя.ВыделенныеСтроки);
	ирОбщий.ЗаписатьТекстВФайлЛкс(ирОбщий.СтрСоединитьЛкс(Массив, Символы.ПС), ИмяФайла);
КонецПроцедуры

Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
	ИзменитьСвернутостьПанельОсобыйЗапуск(Истина, Ложь);
КонецПроцедуры

Функция СохранитьКопиюСпискаБаз(Знач Авто = Ложь) Экспорт
	ФайлТекущегоСписка = Новый Файл(ирОбщий.ИмяФайлаСпискаИнфобазПользователяОСЛкс());
	Если Авто Тогда
		ДатаДляИмени = НачалоМесяца(ТекущаяДата());
		ирОбщий.СократитьГруппуФайловОткатаЛкс(НайтиФайлы(ФайлТекущегоСписка.Путь, ФайлТекущегоСписка.ИмяБезРасширения + "_*"));
	Иначе
		ДатаДляИмени = ТекущаяДата();
	КонецЕсли;
	ФайлаПриемника = Новый Файл(ФайлТекущегоСписка.Путь + ФайлТекущегоСписка.ИмяБезРасширения + "_" + ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(ДатаДляИмени) + ФайлТекущегоСписка.Расширение);
	Если Не ФайлаПриемника.Существует() Тогда
		КопироватьФайл(ФайлТекущегоСписка.ПолноеИмя, ФайлаПриемника.ПолноеИмя);
		ирОбщий.СообщитьЛкс("Копия списка баз сохранена " + ФайлаПриемника.ПолноеИмя);
	КонецЕсли;
	Возврат ФайлТекущегоСписка;
КонецФункции

Процедура ДействияФормыЗагрузитьИзФайла(Кнопка)
	ИмяФайлаТекущегоСписка = ирОбщий.ИмяФайлаСпискаИнфобазПользователяОСЛкс();
	ИмяФайла = ирКлиент.ВыбратьФайлЛкс(, "v8i", "Список баз 1С", ИмяФайлаТекущегоСписка);
	Если ПустаяСтрока(ИмяФайла) Тогда
		Возврат;
	КонецЕсли;
	ТаблицаБазТекущая = ирОбщий.СписокБазПользователяОСЛкс();
	ТаблицаБазФайла = ирОбщий.СписокБазПользователяОСЛкс(ИмяФайла);
	ТекстВопроса = ирОбщий.СтрШаблонЛкс("В текущем списке %1 элементов. В списке из выбранного файла - %2 элементов. Хотите заменить список (копия текущего списка будет сохранена)?",
		ТаблицаБазТекущая.Количество(), ТаблицаБазФайла.Количество());
	Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ОКОтмена);
	Если Ответ = КодВозвратаДиалога.ОК Тогда
		СохранитьКопиюСпискаБаз();
		КопироватьФайл(ИмяФайла, ИмяФайлаТекущегоСписка);
		ОбновитьСписок();
	КонецЕсли;
КонецПроцедуры

Процедура ДействияФормыСоздатьРезервнуюКопию(Кнопка)
	СохранитьКопиюСпискаБаз();
КонецПроцедуры

ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирБазыПользователяОС.Форма.Список");
ЭлементыФормы.БазыПользователя.ОтборСтрок.ПометкаУдаления.Установить(Ложь);
ЭлементыФормы.БазыПользователя.ОтборСтрок.Избранное.Значение = Истина;
мМаксЧислоКлавиш = 5;
ПоказыватьОсобыйЗапуск = Истина;
мХранимыеДанные = Новый Структура;
мХранимыеДанные.Вставить("ХранимыеАтрибуты");
мХранимыеДанные.Вставить("РежимыЗапускаОбычногоПриложения");
мХранимыеДанные.Вставить("ПапкиСостояние");
мХранимыеДанные.Вставить("БазыПользователяСостояние");
