mirror of https://github.com/procxx/kepka.git
				
				
				
			Add import theme to the editor.
This commit is contained in:
		
							parent
							
								
									d85f162bff
								
							
						
					
					
						commit
						dfd63e66ff
					
				|  | @ -1616,7 +1616,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | ||||||
| "lng_theme_editor_need_unlock" = "You need to unlock Telegram to save your theme."; | "lng_theme_editor_need_unlock" = "You need to unlock Telegram to save your theme."; | ||||||
| "lng_theme_editor_done" = "Theme exported successfully!"; | "lng_theme_editor_done" = "Theme exported successfully!"; | ||||||
| "lng_theme_editor_title" = "Edit color palette"; | "lng_theme_editor_title" = "Edit color palette"; | ||||||
| "lng_theme_editor_export_button" = "Export theme"; |  | ||||||
| "lng_theme_editor_save_button" = "Save theme"; | "lng_theme_editor_save_button" = "Save theme"; | ||||||
| 
 | 
 | ||||||
| "lng_theme_editor_create_title" = "Create theme"; | "lng_theme_editor_create_title" = "Create theme"; | ||||||
|  | @ -1630,6 +1629,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL | ||||||
| "lng_theme_editor_link_about" = "Your theme will be updated for all users each time you change it. Anyone can install it using this link.\n\nTheme links must be longer than 5 characters and use a-z, 0-9 and underscores."; | "lng_theme_editor_link_about" = "Your theme will be updated for all users each time you change it. Anyone can install it using this link.\n\nTheme links must be longer than 5 characters and use a-z, 0-9 and underscores."; | ||||||
| 
 | 
 | ||||||
| "lng_theme_editor_menu_export" = "Export theme"; | "lng_theme_editor_menu_export" = "Export theme"; | ||||||
|  | "lng_theme_editor_menu_import" = "Import theme"; | ||||||
| "lng_theme_editor_menu_show" = "Show palette file"; | "lng_theme_editor_menu_show" = "Show palette file"; | ||||||
| 
 | 
 | ||||||
| "lng_payments_not_supported" = "Sorry, Telegram Desktop doesn't support payments yet. Please use one of our mobile apps to do this."; | "lng_payments_not_supported" = "Sorry, Telegram Desktop doesn't support payments yet. Please use one of our mobile apps to do this."; | ||||||
|  |  | ||||||
|  | @ -220,6 +220,9 @@ public: | ||||||
| 	void selectSkip(int direction); | 	void selectSkip(int direction); | ||||||
| 	void selectSkipPage(int delta, int direction); | 	void selectSkipPage(int delta, int direction); | ||||||
| 
 | 
 | ||||||
|  | 	void applyNewPalette(const QByteArray &newContent); | ||||||
|  | 	void recreateRows(); | ||||||
|  | 
 | ||||||
| 	~Inner() { | 	~Inner() { | ||||||
| 		if (_context.box) _context.box->closeBox(); | 		if (_context.box) _context.box->closeBox(); | ||||||
| 	} | 	} | ||||||
|  | @ -418,7 +421,32 @@ Editor::Inner::Inner(QWidget *parent, const QString &path) : TWidget(parent) | ||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Editor::Inner::recreateRows() { | ||||||
|  | 	_existingRows.create(this, EditorBlock::Type::Existing, &_context); | ||||||
|  | 	_existingRows->show(); | ||||||
|  | 	_newRows.create(this, EditorBlock::Type::New, &_context); | ||||||
|  | 	_newRows->show(); | ||||||
|  | 	if (!readData()) { | ||||||
|  | 		error(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Editor::Inner::prepare() { | void Editor::Inner::prepare() { | ||||||
|  | 	QFile f(_path); | ||||||
|  | 	if (!f.open(QIODevice::ReadOnly)) { | ||||||
|  | 		LOG(("Theme Error: could not open color palette file '%1'").arg(_path)); | ||||||
|  | 		error(); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_paletteContent = f.readAll(); | ||||||
|  | 	if (f.error() != QFileDevice::NoError) { | ||||||
|  | 		LOG(("Theme Error: could not read content from palette file '%1'").arg(_path)); | ||||||
|  | 		error(); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	f.close(); | ||||||
|  | 
 | ||||||
| 	if (!readData()) { | 	if (!readData()) { | ||||||
| 		error(); | 		error(); | ||||||
| 	} | 	} | ||||||
|  | @ -551,19 +579,6 @@ void Editor::Inner::sortByAccentDistance() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Editor::Inner::readExistingRows() { | bool Editor::Inner::readExistingRows() { | ||||||
| 	QFile f(_path); |  | ||||||
| 	if (!f.open(QIODevice::ReadOnly)) { |  | ||||||
| 		LOG(("Theme Error: could not open color palette file '%1'").arg(_path)); |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_paletteContent = f.readAll(); |  | ||||||
| 	if (f.error() != QFileDevice::NoError) { |  | ||||||
| 		LOG(("Theme Error: could not read content from palette file '%1'").arg(_path)); |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| 	f.close(); |  | ||||||
| 
 |  | ||||||
| 	return ReadPaletteValues(_paletteContent, [this](QLatin1String name, QLatin1String value) { | 	return ReadPaletteValues(_paletteContent, [this](QLatin1String name, QLatin1String value) { | ||||||
| 		return feedExistingRow(name, value); | 		return feedExistingRow(name, value); | ||||||
| 	}); | 	}); | ||||||
|  | @ -598,6 +613,10 @@ void Editor::Inner::applyEditing(const QString &name, const QString ©Of, QCo | ||||||
| 		auto addedline = (_paletteContent.endsWith('\n') ? "" : newline); | 		auto addedline = (_paletteContent.endsWith('\n') ? "" : newline); | ||||||
| 		newContent = _paletteContent + addedline + plainName + ": " + plainValue + ";" + newline; | 		newContent = _paletteContent + addedline + plainName + ": " + plainValue + ";" + newline; | ||||||
| 	} | 	} | ||||||
|  | 	applyNewPalette(newContent); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Editor::Inner::applyNewPalette(const QByteArray &newContent) { | ||||||
| 	QFile f(_path); | 	QFile f(_path); | ||||||
| 	if (!f.open(QIODevice::WriteOnly)) { | 	if (!f.open(QIODevice::WriteOnly)) { | ||||||
| 		LOG(("Theme Error: could not open '%1' for writing a palette update.").arg(_path)); | 		LOG(("Theme Error: could not open '%1' for writing a palette update.").arg(_path)); | ||||||
|  | @ -704,6 +723,11 @@ void Editor::showMenu() { | ||||||
| 			exportTheme(); | 			exportTheme(); | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
|  | 	_menu->addAction(tr::lng_theme_editor_menu_import(tr::now), [=] { | ||||||
|  | 		App::CallDelayed(st::defaultRippleAnimation.hideDuration, this, [=] { | ||||||
|  | 			importTheme(); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
| 	_menu->addAction(tr::lng_theme_editor_menu_show(tr::now), [=] { | 	_menu->addAction(tr::lng_theme_editor_menu_show(tr::now), [=] { | ||||||
| 		File::ShowInFolder(EditingPalettePath()); | 		File::ShowInFolder(EditingPalettePath()); | ||||||
| 	}); | 	}); | ||||||
|  | @ -732,6 +756,48 @@ void Editor::exportTheme() { | ||||||
| 	})); | 	})); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Editor::importTheme() { | ||||||
|  | 	auto filters = QStringList( | ||||||
|  | 		qsl("Theme files (*.tdesktop-theme *.tdesktop-palette)")); | ||||||
|  | 	filters.push_back(FileDialog::AllFilesFilter()); | ||||||
|  | 	const auto callback = crl::guard(this, [=]( | ||||||
|  | 		const FileDialog::OpenResult &result) { | ||||||
|  | 		const auto path = result.paths.isEmpty() | ||||||
|  | 			? QString() | ||||||
|  | 			: result.paths.front(); | ||||||
|  | 		if (path.isEmpty()) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		auto f = QFile(path); | ||||||
|  | 		if (!f.open(QIODevice::ReadOnly)) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		auto object = Object(); | ||||||
|  | 		object.pathAbsolute = QFileInfo(path).absoluteFilePath(); | ||||||
|  | 		object.pathRelative = QDir().relativeFilePath(path); | ||||||
|  | 		object.content = f.readAll(); | ||||||
|  | 		if (object.content.isEmpty()) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		_select->clearQuery(); | ||||||
|  | 		const auto parsed = ParseTheme(object, false, false); | ||||||
|  | 		_inner->applyNewPalette(parsed.palette); | ||||||
|  | 		_inner->recreateRows(); | ||||||
|  | 		updateControlsGeometry(); | ||||||
|  | 		auto image = App::readImage(parsed.background); | ||||||
|  | 		if (!image.isNull() && !image.size().isEmpty()) { | ||||||
|  | 			Background()->set(Data::CustomWallPaper(), std::move(image)); | ||||||
|  | 			Background()->setTile(parsed.tiled); | ||||||
|  | 			Ui::ForceFullRepaint(_window->widget()); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 	FileDialog::GetOpenPath( | ||||||
|  | 		this, | ||||||
|  | 		tr::lng_theme_editor_menu_import(tr::now), | ||||||
|  | 		filters.join(qsl(";;")), | ||||||
|  | 		crl::guard(this, callback)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| QByteArray Editor::ColorizeInContent( | QByteArray Editor::ColorizeInContent( | ||||||
| 		QByteArray content, | 		QByteArray content, | ||||||
| 		const Colorizer &colorizer) { | 		const Colorizer &colorizer) { | ||||||
|  | @ -754,6 +820,10 @@ void Editor::save() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Editor::resizeEvent(QResizeEvent *e) { | void Editor::resizeEvent(QResizeEvent *e) { | ||||||
|  | 	updateControlsGeometry(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Editor::updateControlsGeometry() { | ||||||
| 	_save->resizeToWidth(width()); | 	_save->resizeToWidth(width()); | ||||||
| 	_close->moveToRight(0, 0); | 	_close->moveToRight(0, 0); | ||||||
| 	_menuToggle->moveToRight(_close->width(), 0); | 	_menuToggle->moveToRight(_close->width(), 0); | ||||||
|  |  | ||||||
|  | @ -65,8 +65,10 @@ private: | ||||||
| 	void save(); | 	void save(); | ||||||
| 	void showMenu(); | 	void showMenu(); | ||||||
| 	void exportTheme(); | 	void exportTheme(); | ||||||
|  | 	void importTheme(); | ||||||
| 	void closeEditor(); | 	void closeEditor(); | ||||||
| 	void closeWithConfirmation(); | 	void closeWithConfirmation(); | ||||||
|  | 	void updateControlsGeometry(); | ||||||
| 
 | 
 | ||||||
| 	const not_null<Window::Controller*> _window; | 	const not_null<Window::Controller*> _window; | ||||||
| 	const Data::CloudTheme _cloud; | 	const Data::CloudTheme _cloud; | ||||||
|  |  | ||||||
|  | @ -224,7 +224,6 @@ bool PaletteChanged( | ||||||
| void ImportFromFile( | void ImportFromFile( | ||||||
| 		not_null<Main::Session*> session, | 		not_null<Main::Session*> session, | ||||||
| 		not_null<QWidget*> parent) { | 		not_null<QWidget*> parent) { | ||||||
| 	const auto &imgExtensions = cImgExtensions(); |  | ||||||
| 	auto filters = QStringList( | 	auto filters = QStringList( | ||||||
| 		qsl("Theme files (*.tdesktop-theme *.tdesktop-palette)")); | 		qsl("Theme files (*.tdesktop-theme *.tdesktop-palette)")); | ||||||
| 	filters.push_back(FileDialog::AllFilesFilter()); | 	filters.push_back(FileDialog::AllFilesFilter()); | ||||||
|  | @ -239,7 +238,7 @@ void ImportFromFile( | ||||||
| 	}); | 	}); | ||||||
| 	FileDialog::GetOpenPath( | 	FileDialog::GetOpenPath( | ||||||
| 		parent.get(), | 		parent.get(), | ||||||
| 		tr::lng_choose_image(tr::now), | 		tr::lng_theme_editor_menu_import(tr::now), | ||||||
| 		filters.join(qsl(";;")), | 		filters.join(qsl(";;")), | ||||||
| 		crl::guard(parent, callback)); | 		crl::guard(parent, callback)); | ||||||
| } | } | ||||||
|  | @ -278,71 +277,6 @@ void ImportFromFile( | ||||||
| 	return data; | 	return data; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Only is valid for current theme, pass Local::ReadThemeContent() here.
 |  | ||||||
| [[nodiscard]] ParsedTheme ParseTheme( |  | ||||||
| 		const Object &theme, |  | ||||||
| 		bool onlyPalette = false) { |  | ||||||
| 	auto raw = ParsedTheme(); |  | ||||||
| 	raw.palette = theme.content; |  | ||||||
| 	const auto result = [&] { |  | ||||||
| 		if (const auto colorizer = ColorizerForTheme(theme.pathAbsolute)) { |  | ||||||
| 			raw.palette = Editor::ColorizeInContent( |  | ||||||
| 				std::move(raw.palette), |  | ||||||
| 				colorizer); |  | ||||||
| 		} |  | ||||||
| 		raw.palette = ReplaceAdjustableColors(std::move(raw.palette)); |  | ||||||
| 		return raw; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	zlib::FileToRead file(theme.content); |  | ||||||
| 
 |  | ||||||
| 	unz_global_info globalInfo = { 0 }; |  | ||||||
| 	file.getGlobalInfo(&globalInfo); |  | ||||||
| 	if (file.error() != UNZ_OK) { |  | ||||||
| 		return result(); |  | ||||||
| 	} |  | ||||||
| 	raw.palette = file.readFileContent("colors.tdesktop-theme", zlib::kCaseInsensitive, kThemeSchemeSizeLimit); |  | ||||||
| 	if (file.error() == UNZ_END_OF_LIST_OF_FILE) { |  | ||||||
| 		file.clearError(); |  | ||||||
| 		raw.palette = file.readFileContent("colors.tdesktop-palette", zlib::kCaseInsensitive, kThemeSchemeSizeLimit); |  | ||||||
| 	} |  | ||||||
| 	if (file.error() != UNZ_OK) { |  | ||||||
| 		LOG(("Theme Error: could not read 'colors.tdesktop-theme' or 'colors.tdesktop-palette' in the theme file.")); |  | ||||||
| 		return ParsedTheme(); |  | ||||||
| 	} else if (onlyPalette) { |  | ||||||
| 		return result(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	const auto fromFile = [&](const char *filename) { |  | ||||||
| 		raw.background = file.readFileContent(filename, zlib::kCaseInsensitive, kThemeBackgroundSizeLimit); |  | ||||||
| 		if (file.error() == UNZ_OK) { |  | ||||||
| 			return true; |  | ||||||
| 		} else if (file.error() == UNZ_END_OF_LIST_OF_FILE) { |  | ||||||
| 			file.clearError(); |  | ||||||
| 			return true; |  | ||||||
| 		} |  | ||||||
| 		LOG(("Theme Error: could not read '%1' in the theme file.").arg(filename)); |  | ||||||
| 		return false; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	if (!fromFile("background.jpg") || !raw.background.isEmpty()) { |  | ||||||
| 		return raw.background.isEmpty() ? ParsedTheme() : result(); |  | ||||||
| 	} |  | ||||||
| 	raw.isPng = true; |  | ||||||
| 	if (!fromFile("background.png") || !raw.background.isEmpty()) { |  | ||||||
| 		return raw.background.isEmpty() ? ParsedTheme() : result(); |  | ||||||
| 	} |  | ||||||
| 	raw.tiled = true; |  | ||||||
| 	if (!fromFile("tiled.png") || !raw.background.isEmpty()) { |  | ||||||
| 		return raw.background.isEmpty() ? ParsedTheme() : result(); |  | ||||||
| 	} |  | ||||||
| 	raw.isPng = false; |  | ||||||
| 	if (!fromFile("background.jpg") || !raw.background.isEmpty()) { |  | ||||||
| 		return raw.background.isEmpty() ? ParsedTheme() : result(); |  | ||||||
| 	} |  | ||||||
| 	return result(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| QByteArray GenerateDefaultPalette() { | QByteArray GenerateDefaultPalette() { | ||||||
| 	auto result = QByteArray(); | 	auto result = QByteArray(); | ||||||
| 	const auto rows = style::main_palette::data(); | 	const auto rows = style::main_palette::data(); | ||||||
|  | @ -994,5 +928,72 @@ void SaveThemeBox( | ||||||
| 	box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); | 	box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | ParsedTheme ParseTheme( | ||||||
|  | 		const Object &theme, | ||||||
|  | 		bool onlyPalette, | ||||||
|  | 		bool parseCurrent) { | ||||||
|  | 	auto raw = ParsedTheme(); | ||||||
|  | 	raw.palette = theme.content; | ||||||
|  | 	const auto result = [&] { | ||||||
|  | 		if (const auto colorizer = ColorizerForTheme(theme.pathAbsolute)) { | ||||||
|  | 			raw.palette = Editor::ColorizeInContent( | ||||||
|  | 				std::move(raw.palette), | ||||||
|  | 				colorizer); | ||||||
|  | 		} | ||||||
|  | 		if (parseCurrent) { | ||||||
|  | 			raw.palette = ReplaceAdjustableColors(std::move(raw.palette)); | ||||||
|  | 		} | ||||||
|  | 		return raw; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	zlib::FileToRead file(theme.content); | ||||||
|  | 
 | ||||||
|  | 	unz_global_info globalInfo = { 0 }; | ||||||
|  | 	file.getGlobalInfo(&globalInfo); | ||||||
|  | 	if (file.error() != UNZ_OK) { | ||||||
|  | 		return result(); | ||||||
|  | 	} | ||||||
|  | 	raw.palette = file.readFileContent("colors.tdesktop-theme", zlib::kCaseInsensitive, kThemeSchemeSizeLimit); | ||||||
|  | 	if (file.error() == UNZ_END_OF_LIST_OF_FILE) { | ||||||
|  | 		file.clearError(); | ||||||
|  | 		raw.palette = file.readFileContent("colors.tdesktop-palette", zlib::kCaseInsensitive, kThemeSchemeSizeLimit); | ||||||
|  | 	} | ||||||
|  | 	if (file.error() != UNZ_OK) { | ||||||
|  | 		LOG(("Theme Error: could not read 'colors.tdesktop-theme' or 'colors.tdesktop-palette' in the theme file.")); | ||||||
|  | 		return ParsedTheme(); | ||||||
|  | 	} else if (onlyPalette) { | ||||||
|  | 		return result(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	const auto fromFile = [&](const char *filename) { | ||||||
|  | 		raw.background = file.readFileContent(filename, zlib::kCaseInsensitive, kThemeBackgroundSizeLimit); | ||||||
|  | 		if (file.error() == UNZ_OK) { | ||||||
|  | 			return true; | ||||||
|  | 		} else if (file.error() == UNZ_END_OF_LIST_OF_FILE) { | ||||||
|  | 			file.clearError(); | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 		LOG(("Theme Error: could not read '%1' in the theme file.").arg(filename)); | ||||||
|  | 		return false; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	if (!fromFile("background.jpg") || !raw.background.isEmpty()) { | ||||||
|  | 		return raw.background.isEmpty() ? ParsedTheme() : result(); | ||||||
|  | 	} | ||||||
|  | 	raw.isPng = true; | ||||||
|  | 	if (!fromFile("background.png") || !raw.background.isEmpty()) { | ||||||
|  | 		return raw.background.isEmpty() ? ParsedTheme() : result(); | ||||||
|  | 	} | ||||||
|  | 	raw.tiled = true; | ||||||
|  | 	if (!fromFile("tiled.png") || !raw.background.isEmpty()) { | ||||||
|  | 		return raw.background.isEmpty() ? ParsedTheme() : result(); | ||||||
|  | 	} | ||||||
|  | 	raw.isPng = false; | ||||||
|  | 	if (!fromFile("background.jpg") || !raw.background.isEmpty()) { | ||||||
|  | 		return raw.background.isEmpty() ? ParsedTheme() : result(); | ||||||
|  | 	} | ||||||
|  | 	return result(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace Theme
 | } // namespace Theme
 | ||||||
| } // namespace Window
 | } // namespace Window
 | ||||||
|  |  | ||||||
|  | @ -19,6 +19,9 @@ class Controller; | ||||||
| 
 | 
 | ||||||
| namespace Theme { | namespace Theme { | ||||||
| 
 | 
 | ||||||
|  | struct Object; | ||||||
|  | struct ParsedTheme; | ||||||
|  | 
 | ||||||
| void StartEditor( | void StartEditor( | ||||||
| 	not_null<Window::Controller*> window, | 	not_null<Window::Controller*> window, | ||||||
| 	const Data::CloudTheme &cloud); | 	const Data::CloudTheme &cloud); | ||||||
|  | @ -46,5 +49,10 @@ void SaveThemeBox( | ||||||
| 
 | 
 | ||||||
| [[nodiscard]] QByteArray CollectForExport(const QByteArray &palette); | [[nodiscard]] QByteArray CollectForExport(const QByteArray &palette); | ||||||
| 
 | 
 | ||||||
|  | [[nodiscard]] ParsedTheme ParseTheme( | ||||||
|  | 	const Object &theme, | ||||||
|  | 	bool onlyPalette = false, | ||||||
|  | 	bool parseCurrent = true); | ||||||
|  | 
 | ||||||
| } // namespace Theme
 | } // namespace Theme
 | ||||||
| } // namespace Window
 | } // namespace Window
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue