⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packagetab.cc

📁 About: Paco (pacKAGE oRGANIZER) is a simple, yet powerful tool to aid package management when insta
💻 CC
字号:
//=======================================================================// PackageTab.cc//-----------------------------------------------------------------------// This file is part of the package paco// Copyright (C) 2004-2007 David Rosal <david.3r@gmail.com>// For more information visit http://paco.sourceforge.net//=======================================================================#include "config.h"#include "Config.h"#include "globals.h"#include "Lock.h"#include "PackageTab.h"#include "PkgWindow.h"#include "MainWindow.h"#include "Pkg.h"#include "paco/File.h"#include <gtkmm/separator.h>#include <gtkmm/label.h>#include <gtkmm/table.h>#include <gtkmm/tooltips.h>#include <gtkmm/stock.h>#include <gtkmm/sizegroup.h>#include <gtkmm/progressbar.h>#include <glibmm/iochannel.h>#include <glibmm/spawn.h>#include <fstream>#include <sstream>using sigc::mem_fun;using std::vector;using std::string;using Glib::ustring;using namespace Gpaco;static void unlinkAsync(string const&);PackageTab::Last PackageTab::sLast =	{ Glib::get_home_dir(), GZIP, 8, false };PackageTab::PackageTab(Pkg& pkg):	Gtk::VBox(),	mPkg(pkg),	mLabel("", 0.02, 0.5),	mLabelTarball(pkg.name() + ".paco.tar.gz", 0.0, 0.0),	mComboProg(),	mComboLevel(),	mFileChooserButton(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER),	mButtonCreate(Gtk::Stock::EXECUTE, "C_reate"),	mButtonClose(Gtk::Stock::CLOSE, "_Close"),	mButtonStop(Gtk::Stock::STOP, "_Stop"),	mButtonTest("_Integrity test", true),	mStop(false),	mProgressBar(){	mLabel.set_ellipsize(Pango::ELLIPSIZE_MIDDLE);	mLabelTarball.set_ellipsize(Pango::ELLIPSIZE_MIDDLE);	mFileChooserButton.set_show_hidden();	mFileChooserButton.set_current_folder(sLast.folder);	mComboProg.append_text("gzip");	mComboProg.append_text("bzip2");	mComboProg.signal_changed().connect(mem_fun		(*this, &PackageTab::onChangeProg));	mComboProg.set_active(sLast.prog);	mComboLevel.append_text("1 (faster)");	char num[2];	for (int i = 2; i < 9; ++i) {		g_snprintf(num, sizeof(num), "%d", i);		mComboLevel.append_text(num);	}	mComboLevel.append_text("9 (better)");	mComboLevel.set_active(sLast.level);	gpTips->set_tip(mButtonTest, "Make an integrity test after creating "		"the package (option -t in gzip and bzip2)");	Gtk::Table* pTable(Gtk::manage(new Gtk::Table(4, 4)));	pTable->set_row_spacings(10);	pTable->set_col_spacings(10);	pTable->attach(*(Gtk::manage(new Gtk::Label		("Name:", 0., 0.5))), 0, 1, 0, 1, Gtk::FILL);	pTable->attach(mLabelTarball, 1, 4, 0, 1);	pTable->attach(*(Gtk::manage(new Gtk::Label		("Save in folder:", 0., 0.5))), 0, 1, 1, 2, Gtk::FILL);	pTable->attach(mFileChooserButton, 1, 4, 1, 2);	pTable->attach(*(Gtk::manage(new Gtk::Label		("Compression:", 0., 0.5))), 0, 1, 2, 3, Gtk::FILL);	pTable->attach(mComboProg, 1, 2, 2, 3);	pTable->attach(*(Gtk::manage(new Gtk::Label		("Level:", 0., 0.5))), 2, 3, 2, 3, Gtk::SHRINK);	pTable->attach(mComboLevel, 3, 4, 2, 3, Gtk::FILL);	pTable->attach(mButtonTest, 0, 4, 3, 4,		Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND, 0, 8);	Gtk::HBox* pHBoxTable(Gtk::manage(new Gtk::HBox()));	pHBoxTable->pack_start(*pTable, Gtk::PACK_EXPAND_WIDGET, 8);	mButtonCreate.signal_clicked().connect(mem_fun		(*this, &PackageTab::onCreate));	mButtonClose.signal_clicked().connect(mem_fun		(*this, &PackageTab::onClose));	mButtonStop.signal_clicked().connect(mem_fun		(*this, &PackageTab::onStop));	Glib::RefPtr<Gtk::SizeGroup> pSizeGroup(Gtk::SizeGroup::create		(Gtk::SIZE_GROUP_HORIZONTAL));	pSizeGroup->add_widget(mButtonClose);	pSizeGroup->add_widget(mButtonStop);	Gtk::HBox* pHBoxButtons(Gtk::manage(new Gtk::HBox()));	pHBoxButtons->pack_start(mButtonCreate, Gtk::PACK_SHRINK, 8);	pHBoxButtons->pack_end(mButtonClose, Gtk::PACK_SHRINK, 8);	pHBoxButtons->pack_end(mButtonStop, Gtk::PACK_SHRINK, 8);	mProgressBar.set_size_request(-1, 0);	mProgressBar.set_pulse_step(0.007);	Gtk::HBox* pHBoxStatusBar(Gtk::manage(new Gtk::HBox()));	pHBoxStatusBar->pack_start(mLabel, true, true);	pHBoxStatusBar->pack_end(mProgressBar, false, false);	pack_start(*(Gtk::manage(new Gtk::HBox())), Gtk::PACK_SHRINK, 4);	pack_start(*pHBoxTable, Gtk::PACK_SHRINK, 8);	pack_start(*(Gtk::manage(new Gtk::HBox())));	pack_start(*pHBoxButtons, Gtk::PACK_SHRINK, 8);	pack_start(*(Gtk::manage(new Gtk::HSeparator)), Gtk::PACK_SHRINK);	pack_start(*pHBoxStatusBar, Gtk::PACK_SHRINK);	checkLock();	Glib::signal_timeout().connect(mem_fun		(*this, &PackageTab::checkLock), 500, Glib::PRIORITY_HIGH);		show_all();	mProgressBar.hide();	mButtonStop.hide();}PackageTab::~PackageTab(){	sLast.folder = mFileChooserButton.get_filename();	sLast.test = mButtonTest.get_active();	sLast.level = mComboLevel.get_active_row_number();	sLast.prog = mComboProg.get_active_row_number();	mStop = true;	Glib::usleep(30000);}bool PackageTab::checkLock(){	Lock::setLock(mButtonCreate);	return true;}//---------//// private ////---------//void PackageTab::lock(bool set /* = true */){	g_assert(Lock::locked() == !set);	Lock::lock(set);	Lock::setLock(mFileChooserButton);	Lock::setLock(mComboProg);	Lock::setLock(mComboLevel);}void PackageTab::onCreate(){	mStop = false;	// Check whether we have write permissions on the dest. directory	ustring dir = mFileChooserButton.get_filename();	if (access(dir.c_str(), W_OK) < 0) {		errorDialog(mPkg.window(), dir + ": " + Glib::strerror(errno));		return;	}	int prog = mComboProg.get_active_row_number();	string tar(dir + "/" + mPkg.name() + ".paco.tar");	string zip(tar + (prog == GZIP ? ".gz" : ".bz2"));	if (!access(zip.c_str(), F_OK)) {		if (!questionDialog(mPkg.window(), "File " + zip + 			" already exists.\nDo you want to overwrite it ?"))			return;	}	bool done = false;	string tmpFile;	int fd = Glib::file_open_tmp(tmpFile);	g_return_if_fail(fd > 0);	close(fd);	std::ofstream ftmp(tmpFile.c_str());	g_return_if_fail(ftmp);	struct stat s;	vector<string> argv;	int level = mComboLevel.get_active_row_number() + 1;	g_assert(level > 0 && level < 10);	std::ostringstream levelOpt;	levelOpt << "-" << level;	lock();	mButtonStop.show();	mButtonClose.hide();	mProgressBar.show();		mLabel.set_text("Reading logged files");	refreshMainLoop();	for (Pkg::iterator f = mPkg.begin(); f != mPkg.end(); ++f) {		if (!lstat((*f)->name().c_str(), &s))			ftmp << (*f)->name() << "\n";	}	if (!ftmp.tellp()) {		errorDialog(mPkg.window(), "Empty package");		goto ____return;	}	ftmp.close();		argv.push_back("tar");	argv.push_back("--create");	argv.push_back("--file=" + tar);	argv.push_back("--files-from=" + tmpFile);	argv.push_back("--ignore-failed-read");	mLabel.set_text("Creating " + tar);	refreshMainLoop();	if (!spawnAsync(argv)) {		unlinkAsync(tar);		goto ____return;	}	argv.clear();	argv.push_back(prog == GZIP ? "gzip" : "bzip2");	argv.push_back(levelOpt.str());	argv.push_back("--force");	argv.push_back(tar);		mLabel.set_text("Creating " + zip);	refreshMainLoop();	if (!spawnAsync(argv)) {		unlinkAsync(tar);		unlinkAsync(zip);		goto ____return;	}	if (!mButtonTest.get_active()) {		done = true;		goto ____return;	}		argv.clear();	argv.push_back(prog == GZIP ? "gzip" : "bzip2");	argv.push_back("--test");	argv.push_back(zip);	mLabel.set_text("Testing " + zip);	refreshMainLoop();	done = spawnAsync(argv);____return:	unlink(tmpFile.c_str());	lock(false);	if (mPkg.window()) {		mProgressBar.hide();		mButtonStop.hide();		mButtonClose.show();		mLabel.set_text(done ? "Done" : "");		mStop = false;	}	refreshMainLoop();}void PackageTab::onClose(){	mPkg.deleteWindow();}void PackageTab::onStop(){	g_assert(mStop == false);	mStop = true;}void PackageTab::onChangeProg(){	switch (mComboProg.get_active_row_number()) {		case GZIP:			mLabelTarball.set_text(mPkg.name() + ".paco.tar.gz");			break;		case BZIP2:			mLabelTarball.set_text(mPkg.name() + ".paco.tar.bz2");			break;		default:			g_assert_not_reached();	}}bool PackageTab::spawnAsync(vector<string>& argv){	Glib::Pid pid;	int stdErr, status, cnt = 0;	Glib::spawn_async_with_pipes(Glib::get_current_dir(), argv,		Glib::SPAWN_DO_NOT_REAP_CHILD | Glib::SPAWN_SEARCH_PATH,		sigc::slot<void>(), &pid, NULL, NULL, &stdErr);	Glib::RefPtr<Glib::IOChannel> io = Glib::IOChannel::create_from_fd(stdErr);	io->set_close_on_unref(true);	while (waitpid(pid, &status, WNOHANG) != pid) {		if (mStop) {			kill(pid, cnt++ ? SIGKILL : SIGTERM);			Glib::usleep(20000);		}		else {			mProgressBar.pulse();			refreshMainLoop();		}		Glib::usleep(2000);		}	bool retVal = true;	if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) {		if (!mStop) {			ustring aux, err = "Error while running the " + argv[0] + " process";			if (io->read_to_end(aux) == Glib::IO_STATUS_NORMAL)				err += ":\n\n" + aux;			errorDialog(mPkg.window(), err);		}		retVal = false;	}	return retVal;}static void unlinkAsync(string const& file){	vector<string> argv;	argv.push_back("unlink");	argv.push_back(file);	Glib::spawn_async(Glib::get_current_dir(), argv, Glib::SPAWN_SEARCH_PATH		| Glib::SPAWN_STDOUT_TO_DEV_NULL | Glib::SPAWN_STDERR_TO_DEV_NULL);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -