📄 packagetab.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 + -