📄 filestreeview.cc
字号:
//=======================================================================// FilesTreeView.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 "Pkg.h"#include "PkgWindow.h"#include "FilesTab.h"#include "FilesTreeView.h"#include "paco/File.h"#include <sstream>#include <algorithm>#include <gtkmm/liststore.h>#include <gtkmm/uimanager.h>#include <gtkmm/actiongroup.h>#include <gtkmm/menu.h>#include <gtkmm/stock.h>#include <gtkmm/progressbar.h>#include <glibmm/spawn.h>#define CHECK_PKG_WINDOW \ if (!mPkg.window() || mPkg.window()->deleting()) returnusing Glib::ustring;using sigc::mem_fun;using sigc::bind;using sigc::slot;using std::vector;using std::string;using std::remove_if;using namespace Gpaco;// Forward declsstatic bool isMissing(File*);static bool isBzip2(string const&);static bool isGzip(string const&);static bool isRegular(string const&);//--------//// public ////--------//FilesTreeView::FilesTreeView(Pkg& pkg): Gtk::TreeView(), mPkg(pkg), mColumns(), mpModelAll(Gtk::ListStore::create(mColumns)), mpModelInst(Gtk::ListStore::create(mColumns)), mpModelMiss(Gtk::ListStore::create(mColumns)), mpModelEmpty(Gtk::ListStore::create(mColumns)), mppModel(NULL), mpMenu(NULL), mpUIManager(Gtk::UIManager::create()), mpActionGroup(Gtk::ActionGroup::create()), mpActionStrip(Gtk::Action::create("Strip", "_Strip")), mpActionCompress(Gtk::Action::create("Compress", "_Compress")), mpActionUncompress(Gtk::Action::create("Uncompress", "_Uncompress")), mpActionRemove(Gtk::Action::create("Remove", Gtk::Stock::DELETE, "_Remove...")), mpActionSelectAll(Gtk::Action::create("SelectAll", "Select _all")), mpActionUnselectAll(Gtk::Action::create("UnselectAll", "_Unselect all")){ set_rules_hint(Config::rules()); (get_selection())->set_mode(Gtk::SELECTION_MULTIPLE); Glib::RefPtr<Gtk::ListStore>* pModel[3] = { &mpModelAll, &mpModelInst, &mpModelMiss }; for (int i = 0; i < 3; ++i) { (*pModel[i])->set_sort_func(COL_STATUS, mem_fun (*this, &FilesTreeView::statusSortFunc)); (*pModel[i])->set_sort_func(COL_NAME, mem_fun (*this, &FilesTreeView::nameSortFunc)); (*pModel[i])->set_sort_func(COL_SIZE, mem_fun (*this, &FilesTreeView::sizeSortFunc)); } setModel(); // Status column int id = append_column("", mColumns.mStatus) - 1; g_assert(id == COL_STATUS); Gtk::TreeViewColumn* pCol = get_column(id); Gtk::CellRenderer* pCell = pCol->get_first_cell_renderer(); pCol->set_sort_column(id); pCol->set_cell_data_func(*pCell, mem_fun (*this, &FilesTreeView::statusCellFunc)); // Column "File" id = append_column("File", mColumns.mName) - 1; g_assert(id == COL_NAME); pCol = get_column(id); pCell = pCol->get_first_cell_renderer(); pCol->set_sort_column(id); pCol->set_resizable(); pCol->set_cell_data_func(*pCell, mem_fun (*this, &FilesTreeView::nameCellFunc)); // Column "Size" id = append_column("Size", mColumns.mSize) - 1; g_assert(id == COL_SIZE); pCol = get_column(id); pCell = pCol->get_first_cell_renderer(); pCol->set_sort_column(id); pCol->set_resizable(); pCol->set_alignment(1.0); pCol->set_cell_data_func(*pCell, mem_fun (*this, &FilesTreeView::sizeCellFunc)); pCell->property_xalign() = 1.0; // Build the popup menu mpActionGroup->add(mpActionStrip); mpActionGroup->add(Gtk::Action::create("StripAll", "_All"), bind<int>(mem_fun(*this, &FilesTreeView::onDo), STRIP_ALL)); mpActionGroup->add(Gtk::Action::create("StripDebug", "_Debug"), bind<int>(mem_fun(*this, &FilesTreeView::onDo), STRIP_DEBUG)); mpActionGroup->add(Gtk::Action::create("StripUnneeded", "_Unneeded"), bind<int>(mem_fun(*this, &FilesTreeView::onDo), STRIP_UNNEEDED)); mpActionGroup->add(mpActionCompress); mpActionGroup->add(Gtk::Action::create("CompressGzip", "_Gzip"), bind<int>(mem_fun(*this, &FilesTreeView::onDo), GZIP)); mpActionGroup->add(Gtk::Action::create("CompressBzip2", "_Bzip2"), bind<int>(mem_fun(*this, &FilesTreeView::onDo), BZIP2)); mpActionGroup->add(mpActionUncompress, bind<int>(mem_fun(*this, &FilesTreeView::onDo), UNCOMPRESS)); mpActionGroup->add(mpActionRemove, mem_fun (*this, &FilesTreeView::onRemove)); mpActionGroup->add(mpActionSelectAll, mem_fun (*this, &FilesTreeView::onSelectAll)); mpActionGroup->add(mpActionUnselectAll, mem_fun (*this, &FilesTreeView::onUnselectAll)); mpUIManager->insert_action_group(mpActionGroup); mpUIManager->add_ui_from_string( "<ui>" " <popup name='PopupMenu'>" " <menu action='Strip'>" " <menuitem action='StripAll'/>" " <menuitem action='StripDebug'/>" " <menuitem action='StripUnneeded'/>" " </menu>" " <menu action='Compress'>" " <menuitem action='CompressGzip'/>" " <menuitem action='CompressBzip2'/>" " </menu>" " <menuitem action='Uncompress'/>" " <menuitem action='Remove'/>" " <separator/>" " <menuitem action='SelectAll'/>" " <menuitem action='UnselectAll'/>" " </popup>" "</ui>"); mpMenu = dynamic_cast<Gtk::Menu*>(mpUIManager->get_widget("/PopupMenu"));}// [virtual]FilesTreeView::~FilesTreeView(){ }//// Re-render all the cells of the tree view//void FilesTreeView::refresh(){ (*mppModel)->foreach(mem_fun(*this, &FilesTreeView::rowChanged)); writeLabel();}void FilesTreeView::writeLabel() const{ if ((*mppModel)->children().empty()) { setLabelText(""); return; } vector<File*> selFiles; long size = 0, files = getSelected(selFiles, &size); if (!files) { g_assert(size == 0); if (mPkg.listFilesInst()) { size += mPkg.sizeInst(); files += mPkg.filesInst(); } if (mPkg.listFilesMiss()) { size += mPkg.sizeMiss(); files += mPkg.filesMiss(); } } std::ostringstream msg; msg << files << " file" << (files > 1 ? "s" : "") << (selFiles.empty() ? "" : " selected") << " | " << Paco::sizeStr(Config::sizeUnit(), size); switch (Config::sizeUnit()) { case Paco::KILOBYTE: msg << 'k'; break; case Paco::MEGABYTE: msg << 'M'; break; case Paco::BYTE: msg << " bytes"; } setLabelText(msg.str());}void FilesTreeView::resetModel(){ vector<File*> sel, visible; getSelected(sel); getVisible(visible); int sortColID; Gtk::SortType sortType; bool sorted = (*mppModel)->get_sort_column_id(sortColID, sortType); unset_model(); mpModelAll->clear(); mpModelInst->clear(); mpModelMiss->clear(); setModel(); // Restore sorting if (sorted) (*mppModel)->set_sort_column_id(sortColID, sortType); // Restore scroll for (vector<File*>::iterator f = visible.begin(); f != visible.end(); ++f) { iterator it; if (getIter(*f, *mppModel, it)) { Gtk::TreePath path(it); scroll_to_row(path, 0.0); break; } } // Restore selection if (sel.empty()) return; Gtk::TreeModel::Children rows = (*mppModel)->children(); if (rows.empty()) return; for (Gtk::TreeModel::Children::iterator r = rows.begin(); r != rows.end(); ++r) { File* file = (*r)[mColumns.mFile]; for (Pkg::iterator f = sel.begin(); f != sel.end(); ++f) { if (file == *f) (get_selection())->select(*r); } }}//---------//// private ////---------//void FilesTreeView::setModel(){ for (Pkg::iterator f = mPkg.begin(); f != mPkg.end(); ++f) { (*mpModelAll->append())[mColumns.mFile] = *f; if ((*f)->missing()) (*mpModelMiss->append())[mColumns.mFile] = *f; else (*mpModelInst->append())[mColumns.mFile] = *f; } if (mPkg.listFilesInst()) mppModel = mPkg.listFilesMiss() ? &mpModelAll : &mpModelInst; else mppModel = mPkg.listFilesMiss() ? &mpModelMiss : &mpModelEmpty; set_model(*mppModel); writeLabel();}//// Get the currently visible files//void FilesTreeView::getVisible(vector<File*>& files){ g_assert(files.empty()); Gtk::TreeModel::Path start, end; if (!get_visible_range(start, end)) return; iterator endIt = (*mppModel)->get_iter(end); for (iterator it = (*mppModel)->get_iter(start); it != endIt; ++it) files.push_back((*it)[mColumns.mFile]);}//// Get the currently selected files//long FilesTreeView::getSelected(vector<File*>& files, long* size /* = NULL */) const{ vector<Gtk::TreeModel::Path> rows = (get_selection())->get_selected_rows(); vector<Gtk::TreeModel::Path>::iterator r; for (r = rows.begin(); r != rows.end(); ++r) { File* file = (*((*mppModel)->get_iter(*r)))[mColumns.mFile]; g_assert(file != NULL); files.push_back(file); if (size && file->size() > 0) *size += file->size(); } return files.size();}void FilesTreeView::onDo(int action){ Lock lock; g_assert(Config::logdirWritable()); // get the selected files vector<File*> files; g_return_if_fail(getSelected(files) > 0L); // show the progress bar Gtk::ProgressBar& progressBar = mPkg.window()->filesTab().progressBar(); progressBar.show(); progressBar.add_modal_grab(); vector<string> argv(3); switch (action) { case STRIP_ALL: argv[0] = "strip"; argv[1] = "--strip-all"; setLabelText("Removing all symbols"); break; case STRIP_DEBUG: argv[0] = "strip"; argv[1] = "--strip-debug"; setLabelText("Removing debug symbols"); break; case STRIP_UNNEEDED: argv[0] = "strip"; argv[1] = "--strip-unneeded"; setLabelText("Removing unneeded symbols"); break; case UNCOMPRESS: argv[1] = "--force";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -