Esempio n. 1
0
void Subtitles::load(const std::string& file_path) throw(m::Exception)
{
	Time_ms time = 0;
	std::string text;
	Glib::ustring line;
	size_t line_num = 1;

	char buf[PIPE_BUF];
	enum { GET_SUBTITLE, GET_TIME, GET_TEXT } state = GET_SUBTITLE;

	Glib::RefPtr<Glib::Regex> tag_regex = Glib::Regex::create("</{0,1}[a-zA-Z]>");
	Glib::RefPtr<Glib::Regex> empty_line_regex = Glib::Regex::create("^\\s*$");
	Glib::RefPtr<Glib::Regex> id_regex = Glib::Regex::create("^\\s*\\d+\\s*$");
	Glib::RefPtr<Glib::Regex> time_regex = Glib::Regex::create(
		"^\\s*(\\d{1,2}):(\\d{1,2}):(\\d{1,2}),(\\d{1,3})\\s+-{1,2}>\\s+\\d{1,2}:\\d{1,2}:\\d{1,2},\\d{1,3}\\s*$"
	);


	this->subtitles.clear();

	// Открываем файл -->
		std::ifstream file;

		file.open(U2L(file_path).c_str(), std::ios::in);
		if(!file.is_open())
			M_THROW(EE(errno));

		file.exceptions(file.eofbit | file.failbit | file.badbit);
	// Открываем файл <--

	while(file.good())
	{
		// Считываем очередную строку из файла -->
		{
			size_t size = 0;

			try
			{
				char byte;
				bool work = true;

				while(work)
				{
					if(size + 1 >= sizeof buf)
						M_THROW(__("line %1 is too big", line_num));

					file.get(byte);

					switch(byte)
					{
						case '\r':
						{
							file.get(byte);

							if(byte != '\n')
								file.unget();
						}
						case '\n':
						{
							line = smart_convert(std::string(buf, buf + size));

							// Отрезаем Byte order mark, если он присутствует
							// (http://en.wikipedia.org/wiki/Byte_order_mark).
							if(line_num == 1 && !line.empty() && line[0] == 0xFEFF)
								line = line.substr(1);

							work = false;
						}
						break;

						default:
							buf[size++] = byte;
							break;
					}
				}
			}
			catch(m::Exception& e)
			{
				// Чтобы деструктор не сгенерировал исключение
				file.exceptions(file.goodbit);
				throw;
			}
			catch(std::ofstream::failure& e)
			{
				// Чтобы деструктор не сгенерировал исключение
				file.exceptions(file.goodbit);

				if(file.bad())
					M_THROW(EE(errno));
				else
				{
					if(state == GET_SUBTITLE || GET_TEXT)
						line = smart_convert(std::string(buf, buf + size));
					else
						M_THROW(__("unexpected end of file at line %1 ('%2')", line_num, line));
				}
			}
		}
		// Считываем очередную строку из файла <--

		// Парсим полученную строку -->
			switch(state)
			{
				case GET_SUBTITLE:
				{
					bool dont_break = false;

					if(!empty_line_regex->match(line))
					{
						if(id_regex->match(line))
							state = GET_TIME;
						// Иногда субтитры не имеют идентификатора
						else if(time_regex->match(line))
						{
							state = GET_TIME;
							dont_break = true;
						}
						else
							M_THROW(__("invalid line %1 ('%2')", line_num, line));
					}

					if(!dont_break)
						break;
				}

				case GET_TIME:
				{
					Glib::StringArrayHandle matches = time_regex->split(line);

					if(matches.size() < 5)
						M_THROW(__("invalid line %1 ('%2')", line_num, line));
					else
					{
						Time_ms hours = boost::lexical_cast<int>(matches.data()[1]);
						Time_ms minutes = boost::lexical_cast<int>(matches.data()[2]);
						Time_ms seconds = boost::lexical_cast<int>(matches.data()[3]);
						Time_ms mseconds = boost::lexical_cast<int>(matches.data()[4]);

						if(
							hours < 0 ||
							minutes < 0 || minutes > 59 ||
							seconds < 0 || seconds > 59 ||
							mseconds < 0 || mseconds > 999
						)
							M_THROW(__("invalid line %1 ('%2')", line_num, line));


						Time_ms gotten_time = ( (hours * 60 + minutes) * 60 + seconds ) * 1000 + mseconds;

						if(gotten_time < time)
						{
							MLIB_SW(__(
								"Gotten smaller time offset than previous at line %1 in subtitles file '%2'.",
								line_num, file_path
							));
						}
						else
							time = gotten_time;
					}

					state = GET_TEXT;
				}
				break;

				case GET_TEXT:
				{
					if(empty_line_regex->match(line))
					{
						if(!text.empty())
						{
							this->subtitles.push_back(Subtitle(time, text));
							text = "";
						}

						state = GET_SUBTITLE;
					}
					else
					{
						line = tag_regex->replace(line, 0, "", static_cast<Glib::RegexMatchFlags>(0));

						if(!text.empty())
							text += "\n";

						text += line;
					}
				}
				break;

				default:
					MLIB_LE();
					break;
			}
		// Парсим полученную строку <--

		line_num++;
	}

	if(this->subtitles.empty())
		M_THROW(_("there is no subtitles in this file"));
}
Esempio n. 2
0
void Settings_window::load_settings(void)
{
	// Client -->
	{
		Private::Client& client = priv->client;
		const Client_settings& client_settings = this->client_settings;

		// GUI -->
		{
			Private::Gui& gui = client.gui;
			const Gui_settings& gui_settings = client_settings.gui;

			// Misc -->
			{
				Private::Gui_misc& misc = gui.misc;

				misc.show_speed_in_window_title->set_active(			gui_settings.show_speed_in_window_title);
				misc.show_zero_values->set_active(						gui_settings.show_zero_values);
				misc.compact_details_tab->set_active(					gui_settings.compact_details_tab);

				misc.gui_update_interval->set_value(					gui_settings.update_interval);
				misc.max_log_lines->set_value(							gui_settings.max_log_lines);

				misc.show_tray_icon->set_active(						gui_settings.show_tray_icon);
				misc.hide_app_to_tray_at_startup->set_active(			gui_settings.hide_app_to_tray_at_startup);
				misc.minimize_to_tray->set_active(						gui_settings.minimize_to_tray);
				misc.close_to_tray->set_active(							gui_settings.close_to_tray);

				misc.download_completed_notification->set_active(		gui_settings.download_completed_notification);
				misc.all_downloads_completed_notification->set_active(	gui_settings.all_downloads_completed_notification);
			}
			// Misc <--

			// Status bar -->
			{
				Private::Status_bar& bar = gui.status_bar;
				const Status_bar_settings& bar_settings = gui_settings.main_window.status_bar;

				bar.download_speed->set_active(			bar_settings.download_speed);
				bar.download_payload_speed->set_active(	bar_settings.download_payload_speed);

				bar.upload_speed->set_active(			bar_settings.upload_speed);
				bar.upload_payload_speed->set_active(	bar_settings.upload_payload_speed);

				bar.download->set_active(				bar_settings.download);
				bar.payload_download->set_active(		bar_settings.payload_download);

				bar.upload->set_active(					bar_settings.upload);
				bar.payload_upload->set_active(			bar_settings.payload_upload);

				bar.share_ratio->set_active(			bar_settings.share_ratio);
				bar.failed->set_active(					bar_settings.failed);
				bar.redundant->set_active(				bar_settings.redundant);
			}
			// Status bar <--
		}
		// GUI <--

		// Main -->
			this->show_add_torrent_dialog.set_active(this->client_settings.gui.show_add_torrent_dialog);

			this->start_torrent_on_adding_check_button.set_active(this->client_settings.user.start_torrent_on_adding);

			this->download_to_button.set_current_folder(U2L(this->client_settings.user.download_to));

			if(this->client_settings.user.copy_finished_to != "")
			{
				this->copy_finished_to_check_button.set_active();
				this->copy_finished_to_button.set_current_folder(U2L(this->client_settings.user.copy_finished_to));
			}
			else
				this->copy_finished_to_check_button.set_active(false);

			this->open_command.set_text(this->client_settings.user.open_command);
		// Main <--
	}
	// Client <--

	// daemon settings -->
	{
		Daemon_settings& settings = this->daemon_settings;

		// Network -->
			// Misc -->
			{
				Private::Network_misc& misc = priv->daemon.network.misc;

				misc.random_port	->set_active(settings.listen_random_port);
				// Сначала задаем to, чтобы обработчик сигнала выставил ограничение для from
				misc.to_port		->set_value(settings.listen_ports_range.second);
				misc.from_port		->set_value(settings.listen_ports_range.first);
				misc.custom_port	->set_active(!settings.listen_random_port);

				misc.current_port->set_label(
					settings.listen_port < m::PORT_MIN ? _("none") : m::to_string(settings.listen_port));

				misc.dht		->set_active(settings.dht);
				misc.lsd		->set_active(settings.lsd);
				misc.upnp		->set_active(settings.upnp);
				misc.natpmp		->set_active(settings.natpmp);
				misc.pex		->set_active(settings.pex);
				misc.smart_ban	->set_active(settings.smart_ban);

				misc.download_rate_limit			->set_value(settings.download_rate_limit);
				misc.upload_rate_limit				->set_value(settings.upload_rate_limit);
				misc.max_uploads					->set_value(settings.max_uploads);
				misc.max_connections				->set_value(settings.max_connections);
				misc.ignore_limits_on_local_network	->set_active(settings.ignore_limits_on_local_network);

				misc.use_max_announce_interval	->set_active(settings.use_max_announce_interval);
				misc.max_announce_interval		->set_value(settings.max_announce_interval / 60);
			}
			// Misc <--

			// IP filter -->
				priv->daemon.network.ip_filter->set_enabled(settings.ip_filter_enabled);
				priv->daemon.network.ip_filter->set(settings.ip_filter);
			// IP filter <--
		// Network <--

		// Automation -->
		{
			Private::Automation& automation = priv->daemon.automation;

			// Auto load -->
			{
				Daemon_settings::Torrents_auto_load& auto_load = daemon_settings.torrents_auto_load;

				automation.load.is->set_active(auto_load.is);
				automation.load.from->set_current_folder(U2L(auto_load.from));
				automation.load.to->set_current_folder(U2L(auto_load.to));
				automation.load.copy->set_active(auto_load.copy);
				automation.load.copy_to->set_current_folder(U2L(auto_load.copy_to));
				automation.load.delete_loaded->set_active(auto_load.delete_loaded);
			}
			// Auto load <--

			// Auto clean -->
			{
				Daemon_settings::Auto_clean& daemon_clean = daemon_settings.torrents_auto_clean;
				Private::Auto_clean& clean = automation.clean;

				clean.max_seeding_time_type = daemon_clean.max_seeding_time_type;
				clean.max_seeding_time->set_value(daemon_clean.max_seeding_time / 60);
				this->auto_clean_widgets_update_for(
					clean.max_seeding_time_type,
					clean.max_seeding_time_type_button,
					clean.max_seeding_time_type_label,
					clean.max_seeding_time
				);

				clean.max_ratio_type = daemon_clean.max_ratio_type;
				clean.max_ratio->set_value(daemon_clean.max_ratio);
				this->auto_clean_widgets_update_for(
					clean.max_ratio_type,
					clean.max_ratio_type_button,
					clean.max_ratio_type_label,
					clean.max_ratio
				);

				clean.max_seeding_torrents_type = daemon_clean.max_seeding_torrents_type;
				clean.max_seeding_torrents->set_value(daemon_clean.max_seeding_torrents);
				this->auto_clean_widgets_update_for(
					clean.max_seeding_torrents_type,
					clean.max_seeding_torrents_type_button,
					clean.max_seeding_torrents_type_label,
					clean.max_seeding_torrents
				);
			}
			// Auto clean <--
		}
		// Automation <--
	}
	// daemon settings <--
}