summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/generic/util/dynamic_set_transform.h4
-rw-r--r--src/gtk/Makefile.am6
-rw-r--r--src/gtk/SConscript6
-rw-r--r--src/gtk/aptitude.glade456
-rw-r--r--src/gtk/globals.cc176
-rw-r--r--src/gtk/globals.h108
-rw-r--r--src/gtk/init.cc178
-rw-r--r--src/gtk/init.h33
-rw-r--r--src/gtk/mainwindow.cc2
-rw-r--r--src/gtk/mainwindow.h4
-rw-r--r--src/gtk/post_event.cc124
-rw-r--r--src/gtk/post_event.h55
-rw-r--r--src/loggers.cc5
-rw-r--r--src/loggers.h6
-rw-r--r--src/main.cc17
15 files changed, 1174 insertions, 6 deletions
diff --git a/src/generic/util/dynamic_set_transform.h b/src/generic/util/dynamic_set_transform.h
index 148f4cf7..19211fc9 100644
--- a/src/generic/util/dynamic_set_transform.h
+++ b/src/generic/util/dynamic_set_transform.h
@@ -47,8 +47,8 @@ namespace aptitude
boost::shared_ptr<dynamic_set<From> > wrapped_set;
boost::function<To (From)> f;
- sigc::signal<To> signal_inserted;
- sigc::signal<To> signal_removed;
+ sigc::signal<void, To> signal_inserted;
+ sigc::signal<void, To> signal_removed;
void handle_inserted(const From &from);
void handle_removed(const From &from);
diff --git a/src/gtk/Makefile.am b/src/gtk/Makefile.am
index 99ca5e46..02102fbe 100644
--- a/src/gtk/Makefile.am
+++ b/src/gtk/Makefile.am
@@ -30,12 +30,16 @@ libgtk_a_SOURCES=\
errortab.h \
filesview.cc \
filesview.h \
+ globals.cc \
+ globals.h \
gui.cc \
gui.h \
hyperlink.cc \
hyperlink.h \
info.cc \
info.h \
+ init.cc \
+ init.h \
mainwindow.cc \
mainwindow.h \
notify.cc \
@@ -46,6 +50,8 @@ libgtk_a_SOURCES=\
packagestab.h \
pkgview.cc \
pkgview.h \
+ post_event.cc \
+ post_event.h \
previewtab.cc \
previewtab.h \
progress.cc \
diff --git a/src/gtk/SConscript b/src/gtk/SConscript
index fc3fec87..e1451680 100644
--- a/src/gtk/SConscript
+++ b/src/gtk/SConscript
@@ -20,12 +20,16 @@ toplevel_srcs = map(File, [
'errortab.h',
'filesview.cc',
'filesview.h',
+ 'globals.cc',
+ 'globals.h',
'gui.cc',
'gui.h',
'hyperlink.cc',
'hyperlink.h',
'info.cc',
'info.h',
+ 'init.cc',
+ 'init.h',
'mainwindow.cc',
'mainwindow.h',
'notify.cc',
@@ -36,6 +40,8 @@ toplevel_srcs = map(File, [
'packagestab.h',
'pkgview.cc',
'pkgview.h',
+ 'post_event.cc',
+ 'post_event.h',
'previewtab.cc',
'previewtab.h',
'progress.cc',
diff --git a/src/gtk/aptitude.glade b/src/gtk/aptitude.glade
index 6a20f613..e3ad0e31 100644
--- a/src/gtk/aptitude.glade
+++ b/src/gtk/aptitude.glade
@@ -2256,4 +2256,460 @@ You can also modify the files by hand, then click "No".</property>
</widget>
</child>
</widget>
+ <widget class="GtkWindow" id="main_window_2">
+ <property name="title" translatable="yes">Aptitude Package Manager</property>
+ <property name="default_width">800</property>
+ <property name="default_height">600</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkMenuBar" id="main_menubar">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_package_run">
+ <property name="label">_Install/Remove Packages</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Perform all pending installs and removals</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="G" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_update_lists">
+ <property name="label">_Update Package List</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Check for new versions of packages</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="U" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_mark_upgradable">
+ <property name="label">Mark Up_gradable</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Mark all upgradable packages which are not held for upgrade</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="U" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_forget_new">
+ <property name="label">_Forget New Packages</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Forget which packages are "new"</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_keep_all">
+ <property name="label">Canc_el Pending Actions</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Cancel all pending installations, removals, holds, and upgrades.</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_clean">
+ <property name="label">C_lean Package Cache</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Delete package files which were previously downloaded</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_autoclean">
+ <property name="label">Clean _Obsolete Files</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Delete package files which can no longer be downloaded</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_reload_cache">
+ <property name="label">_Reload Package Cache</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Reload the package cache</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_sweep">
+ <property name="label">_Play Minesweeper</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Waste time trying to find mines</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem3">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_su_to_root">
+ <property name="label">_Become Root</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Run 'su' to become root; this will restart the program, but your settings will be preserved</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_do_quit">
+ <property name="label">_Quit</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Exit the program</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">E_dit</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_undo_undo">
+ <property name="label">gtk-undo</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Undo the last package operation or group of operations</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem4">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem6">
+ <property name="label">gtk-cut</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem7">
+ <property name="label">gtk-copy</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem8">
+ <property name="label">gtk-paste</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem9">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Package</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu_package">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu5">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_view_edit_columns">
+ <property name="label">_Edit Columns...</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Change which columns are visible in the currently active view.</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem5">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_view_apt_errors">
+ <property name="label">View Apt _Errors</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">View errors that have occurred in the apt system since the program was started.</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_item_find_dependency_paths">
+ <property name="label">Find _Dependency Chains</property>
+ <property name="visible">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip" translatable="yes">Find chains of dependencies linking one package to another.</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem6">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_tab_previous">
+ <property name="label">gtk-go-back</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="F6" signal="activate"/>
+ <accelerator key="Page_Up" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_tab_next">
+ <property name="label">gtk-go-forward</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="F7" signal="activate"/>
+ <accelerator key="Page_Down" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="menu_tab_close">
+ <property name="label">gtk-close</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ <accelerator key="Q" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <accelerator key="W" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="Help">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu7">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkImageMenuItem" id="imagemenuitem10">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolbar" id="main_toolbar">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkToolButton" id="main_toolbutton_dashboard">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Dashboard</property>
+ <property name="stock_id">gtk-home</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbutton1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="main_toolbutton_update">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Update</property>
+ <property name="stock_id">gtk-refresh</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="main_toolbutton_packages">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Packages</property>
+ <property name="stock_id">gtk-new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="main_toolbutton_preview">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Preview</property>
+ <property name="stock_id">gtk-print-preview</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="main_toolbutton_resolver">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Resolver</property>
+ <property name="stock_id">gtk-dialog-info</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="main_toolbutton_installremove">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Install/Remove</property>
+ <property name="stock_id">gtk-apply</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="main_bin">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkProgressBar" id="main_progressbar">
+ <property name="width_request">250</property>
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkStatusbar" id="main_statusbar">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/src/gtk/globals.cc b/src/gtk/globals.cc
new file mode 100644
index 00000000..ab215c25
--- /dev/null
+++ b/src/gtk/globals.cc
@@ -0,0 +1,176 @@
+/** \file globals.cc */
+
+
+// Copyright (C) 2010 Daniel Burrows
+// Copyright 2008-2009 Obey Arthur Liu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include "globals.h"
+
+#include <loggers.h>
+
+#include <boost/make_shared.hpp>
+#include <boost/ref.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <glibmm/init.h>
+#include <gtkmm/main.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+using aptitude::Loggers;
+
+namespace gui
+{
+ namespace globals
+ {
+ // The globals that have to be shared between several routines.
+ namespace
+ {
+ boost::shared_ptr<Gtk::Main> main_loop;
+ bool download_active;
+ }
+
+ Glib::RefPtr<Gnome::Glade::Xml> load_glade(const std::string &argv0)
+ {
+ // The global filename:
+ static std::string glade_filename;
+
+ if(!glade_filename.empty())
+ {
+ try
+ {
+ return Gnome::Glade::Xml::create(glade_filename);
+ }
+ catch(Gnome::Glade::XmlError &err)
+ {
+ LOG_ERROR(Loggers::getAptitudeGtkGlobals(),
+ "Can't load " << glade_filename << ": " << err.what());
+ // Try to find the glade file again anyway.
+ }
+ }
+
+ Glib::RefPtr<Gnome::Glade::Xml> rval;
+
+#ifndef DISABLE_PRIVATE_GLADE_FILE
+ if(!argv0.empty())
+ {
+ // Use the basename of argv0 to find the Glade file.
+ std::string argv0_path;
+ std::string::size_type last_slash = argv0.rfind('/');
+ if(last_slash != std::string::npos)
+ {
+ while(last_slash > 0 && argv0[last_slash - 1] == '/')
+ --last_slash;
+ argv0_path = std::string(argv0, 0, last_slash);
+ }
+ else
+ argv0_path = '.';
+
+ //Loading the .glade file and widgets
+ const std::string glade_main_file = argv0_path + "/gtk/aptitude.glade";
+ try
+ {
+ rval = Gnome::Glade::Xml::create(glade_main_file);
+ }
+ catch(Gnome::Glade::XmlError &err)
+ {
+ LOG_DEBUG(Loggers::getAptitudeGtkGlobals(),
+ "Can't load " << glade_main_file << ": " << err.what());
+ }
+ }
+#endif
+
+ if(!rval)
+ {
+ const std::string glade_main_file =
+ std::string(PKGDATADIR) + "/aptitude.glade";
+
+ try
+ {
+ rval = Gnome::Glade::Xml::create(glade_main_file);
+ }
+ catch(Gnome::Glade::XmlError &err)
+ {
+ LOG_ERROR(Loggers::getAptitudeGtkGlobals(),
+ "Can't load " << glade_main_file << ": " << err.what());
+ }
+ }
+
+ if(rval)
+ {
+ LOG_INFO(Loggers::getAptitudeGtkGlobals(),
+ "UI definition loaded from " << glade_filename);
+ glade_filename = rval->get_filename();
+ }
+
+ return rval;
+ }
+
+ Glib::RefPtr<Gnome::Glade::Xml> load_glade()
+ {
+ return load_glade(std::string());
+ }
+
+ void init_main_loop(int argc, char *argv[])
+ {
+ main_loop = boost::make_shared<Gtk::Main>(boost::ref(argc),
+ boost::ref(argv));
+ }
+
+ void main_quit()
+ {
+ if(main_loop.get() != NULL)
+ {
+ LOG_TRACE(Loggers::getAptitudeGtkGlobals(),
+ "Telling the main loop to quit.");
+
+ main_loop->quit();
+ }
+ else
+ LOG_ERROR(Loggers::getAptitudeGtkGlobals(),
+ "main_quit() invoked with no main loop.");
+ }
+
+ void run_main_loop()
+ {
+ LOG_TRACE(Loggers::getAptitudeGtkGlobals(),
+ "Entering main loop.");
+
+ Gtk::Main::run();
+ }
+
+ bool is_a_download_active()
+ {
+ return download_active;
+ }
+
+ void set_is_a_download_active(bool value)
+ {
+ if(value == download_active)
+ // Something wants to start a download when one is already
+ // running, or stop when one isn't running.
+ LOG_ERROR(Loggers::getAptitudeGtkGlobals(),
+ "Attempt to set the download_active flag to its current value ("
+ << download_active << ").");
+ else
+ download_active = value;
+ }
+ }
+}
diff --git a/src/gtk/globals.h b/src/gtk/globals.h
new file mode 100644
index 00000000..aaa98990
--- /dev/null
+++ b/src/gtk/globals.h
@@ -0,0 +1,108 @@
+/** \file globals.h */ // -*-c++-*-
+
+// Copyright (C) 2010 Daniel Burrows
+// Copyright 2008-2009 Obey Arthur Liu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#ifndef APTITUDE_GTK_GLOBALS_H
+#define APTITUDE_GTK_GLOBALS_H
+
+#include <libglademm/xml.h>
+
+#include <string>
+
+namespace gui
+{
+ /** \brief All the global variables used by the GTK+ gui go in this
+ * namespace.
+ *
+ * Please justify why each one needs to be global. If possible,
+ * define accessor functions instead of directly exposing the
+ * variables.
+ */
+ namespace globals
+ {
+ /** \brief Find and load aptitude's glade file.
+ *
+ * The first time this is called, it saves the file name that
+ * worked (if one did) so it will be returned by future calls to
+ * get_glade_filename(). Each subsequent time, the same glade
+ * file is reloaded.
+ *
+ * This is global because all parts of aptitude should use the
+ * same glade file; it encapsulates the logic necessary to deal
+ * with that.
+ *
+ * \param argv0 The first entry in argv; used to try to find
+ * a local glade file relative to the aptitude
+ * executable.
+ *
+ * \return the newly loaded file, or a \b NULL pointer if the
+ * glade file couldn't be found.
+ */
+ Glib::RefPtr<Gnome::Glade::Xml> load_glade(const std::string &argv0);
+
+ /** \brief Find and load aptitude's previously loaded glade file.
+ *
+ * This routine will fail if load_glade(const std::string &) was
+ * not previously called.
+ */
+ Glib::RefPtr<Gnome::Glade::Xml> load_glade();
+
+ /** \brief Ensure that the main loop is created.
+ *
+ * Global because aptitude has only one main loop.
+ *
+ * \param argc The number of command-line arguments.
+ * \param argv The array of command-line arguments.
+ */
+ void init_main_loop(int argc, char *argv[]);
+
+ /** \brief Exit the main loop (and thus the program).
+ *
+ * Global because aptitude has only one main loop.
+ */
+ void main_quit();
+
+ /** \brief Run the main loop.
+ *
+ * Should only be invoked from the initialization code.
+ *
+ * Global because aptitude has only one main loop.
+ */
+ void run_main_loop();
+
+ /** \brief Check whether a download is currently active.
+ *
+ * Used to ensure that only one download runs at once; global
+ * because downloads should be mutually exclusive across the
+ * entire program.
+ */
+ bool is_a_download_active();
+
+ /** \brief Set the flag that indicates that a download is active.
+ *
+ * Global for the same reason that is_a_download_active is
+ * global.
+ *
+ * \param value The new value of the flag.
+ */
+ void set_is_a_download_active(bool value);
+ }
+}
+
+#endif // APTITUDE_GTK_GLOBALS_H
diff --git a/src/gtk/init.cc b/src/gtk/init.cc
new file mode 100644
index 00000000..b878fe18
--- /dev/null
+++ b/src/gtk/init.cc
@@ -0,0 +1,178 @@
+/** \file init.cc */
+
+// Copyright (C) 2010 Daniel Burrows
+// Copyright 2008-2009 Obey Arthur Liu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include "init.h"
+
+#include "globals.h"
+#include "mainwindow.h"
+#include "post_event.h"
+#include "resolver.h"
+
+#include <apt-pkg/error.h>
+
+#include <boost/lambda/construct.hpp>
+#include <boost/lambda/lambda.hpp>
+
+#include <generic/apt/config_signal.h>
+
+#include <generic/util/dynamic_set_transform.h>
+#include <generic/util/dynamic_set_union.h>
+
+#include <gtk/toplevel/model.h>
+#include <gtk/toplevel/tabs_notebook.h>
+#include <gtk/toplevel/view.h>
+
+using aptitude::util::dynamic_set;
+using aptitude::util::dynamic_set_transform;
+using aptitude::util::dynamic_set_union;
+using aptitude::util::enumerator;
+using boost::lambda::_1;
+using boost::lambda::constructor;
+using boost::shared_ptr;
+using gui::toplevel::area_info;
+using gui::toplevel::area_list;
+using gui::toplevel::create_area_list;
+using gui::toplevel::tab_display_info;
+using gui::toplevel::tab_info;
+using gui::toplevel::view;
+
+// Contains startup code for the GTK+ GUI. Would be called "main",
+// but that leads to ugly namespace conflicts.
+
+namespace gui
+{
+ namespace
+ {
+ void init_style(void)
+ {
+ Gtk::RC::parse_string (
+ "style \"tiny-button-style\""
+ "{"
+ " GtkWidget::focus-padding = 0"
+ " xthickness = 0"
+ " ythickness = 0"
+ "}"
+ "widget \"*.notebook_close_button\" style \"tiny-button-style\"");
+ }
+
+ shared_ptr<area_list> init_areas()
+ {
+ std::vector<shared_ptr<area_info> > areas;
+ return create_area_list(areas);
+ }
+
+ shared_ptr<view> create_main_view(const shared_ptr<area_list> &areas)
+ {
+ shared_ptr<dynamic_set_union<shared_ptr<tab_info> > > all_tabs_set =
+ dynamic_set_union<shared_ptr<tab_info> >::create();
+
+ for(shared_ptr<enumerator<shared_ptr<area_info> > > e = areas->get_areas();
+ e->advance(); )
+ all_tabs_set->insert_set(e->get_current()->get_tabs());
+
+
+ typedef dynamic_set_transform<shared_ptr<tab_info>,
+ shared_ptr<tab_display_info> > upcast_set;
+ shared_ptr<dynamic_set<shared_ptr<tab_display_info> > > all_tabs_view_set =
+ upcast_set::create(all_tabs_set,
+ constructor<boost::shared_ptr<tab_display_info> >());
+
+ // Use a notebook containing all the tabs in all areas for the
+ // time being.
+ //
+ // Eventually a better main view will be used.
+ return create_tabs_notebook(all_tabs_view_set);
+ }
+
+ void do_apt_init()
+ {
+ // \todo Display progress somehow (maybe using the notification
+ // framework?)
+ OpProgress p;
+ apt_init(&p, true, NULL);
+
+ // \todo Support update-on-startup once updating is plumbed
+ // through.
+ //
+ //if(getuid() == 0 && aptcfg->FindB(PACKAGE "::Update-On-Startup", true))
+ //do_update();
+ }
+ }
+
+ bool init(int argc, char **argv)
+ {
+ // Don't crash if a subprocess breaks a pipe.
+ signal(SIGPIPE, SIG_IGN);
+
+ // GTK+ provides a perfectly good routine, gtk_init_check(), to
+ // initialize GTK+ *and report whether the initialization
+ // succeeded*. gtkmm doesn't wrap it. But initializing GTK+
+ // twice won't hurt, so we do that.
+ if(!gtk_init_check(&argc, &argv))
+ return false;
+
+ Glib::init();
+ // If we don't check thread_supported() first, thread_init()
+ // aborts with an error on some architectures. (see Debian bug
+ // #555120)
+ if(!Glib::thread_supported())
+ Glib::thread_init();
+
+ globals::init_post_event();
+
+ // We have to create the main loop object before loading the Glade
+ // file, or Glade goes and pouts in a corner and refuses to do
+ // anything.
+ globals::init_main_loop(argc, argv);
+
+ Glib::RefPtr<Gnome::Glade::Xml> glade = globals::load_glade(argv[0]);
+
+ if(!glade)
+ {
+ _error->Error(_("Unable to load the user interface definition file %s/aptitude.glade."),
+ PKGDATADIR);
+
+ return false;
+ }
+
+ // Set up the style for GTK+ widgets.
+ init_style();
+
+ // Set up the resolver-triggering signals.
+ init_resolver();
+
+ // Postpone apt_init until we enter the main loop, so we get a GUI
+ // progress bar.
+ Glib::signal_idle().connect(sigc::bind_return(sigc::ptr_fun(&do_apt_init),
+ false));
+
+ shared_ptr<area_list> areas = init_areas();
+
+ shared_ptr<view> main_win_view = create_main_view(areas);
+ Gtk::Window *main = create_mainwindow(glade, main_win_view);
+ main->signal_unmap().connect(sigc::ptr_fun(&globals::main_quit));
+ main->show();
+
+ // Run the main loop, exiting when main_win is closed:
+ globals::run_main_loop();
+
+ return true;
+ }
+}
diff --git a/src/gtk/init.h b/src/gtk/init.h
new file mode 100644
index 00000000..58320a28
--- /dev/null
+++ b/src/gtk/init.h
@@ -0,0 +1,33 @@
+/** \file init.h */ // -*-c++-*-
+
+// Copyright 1999-2010 Daniel Burrows
+// Copyright 2008-2009 Obey Arthur Liu
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#ifndef APTITUDE_GTK_INIT_H
+#define APTITUDE_GTK_INIT_H
+
+namespace gui
+{
+ /** \brief Run the GUI frontend to aptitude.
+ *
+ * \return \b true if the GUI was able to start at all.
+ */
+ bool init(int argc, char **argv);
+}
+
+#endif // APTITUDE_GTK_INIT_H
diff --git a/src/gtk/mainwindow.cc b/src/gtk/mainwindow.cc
index a3a2b6c3..25ff3a6e 100644
--- a/src/gtk/mainwindow.cc
+++ b/src/gtk/mainwindow.cc
@@ -68,7 +68,7 @@ namespace gui
const boost::shared_ptr<toplevel::view> &view)
{
main_window *rval;
- glade->get_widget_derived("main_window", rval);
+ glade->get_widget_derived("main_window_2", rval);
rval->set_view(view);
return rval;
diff --git a/src/gtk/mainwindow.h b/src/gtk/mainwindow.h
index 18fb186f..3fa9342c 100644
--- a/src/gtk/mainwindow.h
+++ b/src/gtk/mainwindow.h
@@ -22,8 +22,8 @@
#include <boost/shared_ptr.hpp>
-#include <gtkmm.h>
-#include <libglademm.h>
+#include <gtkmm/window.h>
+#include <libglademm/xml.h>
namespace gui
{
diff --git a/src/gtk/post_event.cc b/src/gtk/post_event.cc
new file mode 100644
index 00000000..09bac14a
--- /dev/null
+++ b/src/gtk/post_event.cc
@@ -0,0 +1,124 @@
+/** \file post_event.cc */
+
+// Copyright (C) 2010 Daniel Burrows
+// Copyright 2008-2009 Obey Arthur Liu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include "post_event.h"
+
+#include <cwidget/generic/threads/threads.h>
+
+#include <glibmm/dispatcher.h>
+
+#include <deque>
+
+namespace gui
+{
+ namespace globals
+ {
+ namespace
+ {
+ // Code related to injecting events into the main loop:
+
+ // The Glib::dispatch mechanism only allows us to wake the main
+ // thread up; it doesn't allow us to pass actual information
+ // across the channel. To hack this together, I borrow the
+ // event_queue abstraction from cwidget, and use a dispatcher
+ // for the sole purpose of waking the main thread up.
+ //
+ // I believe that putting sigc++ slots on this list should be
+ // OK: from the sigc++ code, it looks like they get passed by
+ // value, not by reference. Once the slot is safely stuck into
+ // the list, everything should be OK.
+
+ cwidget::threads::mutex background_events_mutex;
+ // Set to "true" if the background events function is currently
+ // executing a thunk, in which case we don't need to invoke the
+ // dispatcher. This avoids trouble caused by the thunk invoking
+ // post_event() and filling up the queue, so it deadlocks
+ // itself.
+ bool run_background_events_active = false;
+ bool background_events_dispatcher_signalled = false;
+ std::deque<safe_slot0<void> > background_events;
+ Glib::Dispatcher background_events_dispatcher;
+
+ // Used to ensure that run_background_events_active is true only
+ // while the inner portion of the "while" loop below is running.
+ class set_bool_in_scope
+ {
+ bool &target;
+
+ public:
+ set_bool_in_scope(bool &_target)
+ : target(_target)
+ {
+ target = true;
+ }
+
+ ~set_bool_in_scope()
+ {
+ target = false;
+ }
+ };
+
+ void run_background_events()
+ {
+ cwidget::threads::mutex::lock l(background_events_mutex);
+ while(!background_events.empty())
+ {
+ set_bool_in_scope setter(run_background_events_active);
+ safe_slot0<void> f = background_events.front();
+ background_events.pop_front();
+
+ l.release();
+ f.get_slot()();
+ l.acquire();
+ }
+ background_events_dispatcher_signalled = false;
+ }
+ }
+
+ // Interface routines to the background event code.
+ void post_event(const safe_slot0<void> &event)
+ {
+ // Ensure that the dispatcher is only invoked once.
+ cwidget::threads::mutex::lock l(background_events_mutex);
+ background_events.push_back(event);
+ if(!run_background_events_active && !background_events_dispatcher_signalled)
+ {
+ background_events_dispatcher();
+ background_events_dispatcher_signalled = true;
+ }
+ }
+
+ void post_thunk(const sigc::slot<void> &thunk)
+ {
+ post_event(make_safe_slot(thunk));
+ }
+
+ void init_post_event()
+ {
+ // Defensive programming: ensure that there's only one
+ // connection even if we're called multiple times.
+ static sigc::connection background_events_connection;
+
+ background_events_connection.disconnect();
+ background_events_connection =
+ background_events_dispatcher.connect(sigc::ptr_fun(&run_background_events));
+ }
+ }
+}
diff --git a/src/gtk/post_event.h b/src/gtk/post_event.h
new file mode 100644
index 00000000..c2b666cb
--- /dev/null
+++ b/src/gtk/post_event.h
@@ -0,0 +1,55 @@
+/** \file post_event.h */ // -*-c++-*-
+
+// Copyright (C) 2010 Daniel Burrows
+// Copyright 2008-2009 Obey Arthur Liu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#ifndef POST_EVENT_H
+#define POST_EVENT_H
+
+#include <generic/util/safe_slot.h>
+
+namespace gui
+{
+ namespace globals
+ {
+ // This code is not in globals.{cc,h] because it's more involved
+ // than the other stuff in that file.
+
+ /** \brief Dispatch the given safe thunk to the main loop.
+ *
+ * Global because there is only one main loop and IT DOES NOT
+ * SHARE POWER^W^W^W^W^Wit has only one event queue.
+ */
+ void post_event(const safe_slot0<void> &thunk);
+
+ /** \brief Post an event to the main loop's event queue,
+ * thread-safely.
+ *
+ * Global because there is only one main loop and it has only one
+ * event queue.
+ */
+ void post_thunk(const sigc::slot<void> &thunk);
+
+ /** \brief Initialize support for post_thunk() and
+ * post_event().
+ */
+ void init_post_event();
+ }
+}
+
+#endif // POST_EVENT_H
diff --git a/src/loggers.cc b/src/loggers.cc
index 4c905e3a..fb102407 100644
--- a/src/loggers.cc
+++ b/src/loggers.cc
@@ -103,6 +103,11 @@ namespace aptitude
return Logger::getLogger("aptitude.gtk.dashboard.upgrade.resolver");
}
+ LoggerPtr Loggers::getAptitudeGtkGlobals()
+ {
+ return Logger::getLogger("aptitude.gtk.globals");
+ }
+
LoggerPtr Loggers::getAptitudeGtkMainWindow()
{
return Logger::getLogger("aptitude.gtk.mainwindow");
diff --git a/src/loggers.h b/src/loggers.h
index a8724507..8ae07949 100644
--- a/src/loggers.h
+++ b/src/loggers.h
@@ -153,6 +153,12 @@ namespace aptitude
*/
static logging::LoggerPtr getAptitudeGtkChangelogParse();
+ /** \brief The logger for the module of globals.
+ *
+ * Name: aptitude.gtk.globals
+ */
+ static logging::LoggerPtr getAptitudeGtkGlobals();
+
/** \brief The logger for the GTK+ main window.
*
* Name: aptitude.gtk.mainwindow
diff --git a/src/main.cc b/src/main.cc
index 8ce0cdfe..1f232db2 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -86,6 +86,7 @@
#ifdef HAVE_GTK
#include "gtk/gui.h"
+#include "gtk/init.h"
#endif
#include "loggers.h"
@@ -259,6 +260,7 @@ enum {
OPTION_CLEAN_ON_STARTUP,
OPTION_GROUP_BY,
OPTION_SHOW_PACKAGE_NAMES,
+ OPTION_NEW_GUI,
};
int getopt_result;
@@ -312,6 +314,7 @@ option opts[]={
{"clean-on-startup", 0, &getopt_result, OPTION_CLEAN_ON_STARTUP},
{"group-by", 1, &getopt_result, OPTION_GROUP_BY},
{"show-package-names", 1, &getopt_result, OPTION_SHOW_PACKAGE_NAMES},
+ {"new-gui", 0, &getopt_result, OPTION_NEW_GUI},
{0,0,0,0}
};
@@ -626,6 +629,8 @@ int main(int argc, char *argv[])
#ifdef HAVE_GTK
// TODO: this should be a configuration option.
bool gui = aptcfg->FindB(PACKAGE "::Start-Gui", true);
+ // Use the in-progress new GUI harness instead of the old code.
+ bool use_new_gui = false;
#endif
int curopt;
@@ -905,6 +910,10 @@ int main(int argc, char *argv[])
show_package_names_mode_string = optarg;
break;
+ case OPTION_NEW_GUI:
+ use_new_gui = true;
+ break;
+
default:
fprintf(stderr, "%s",
_("WEIRDNESS: unknown option code received\n"));
@@ -914,6 +923,7 @@ int main(int argc, char *argv[])
getopt_result=0;
break;
+
default:
fprintf(stderr, "%s",
_("WEIRDNESS: unknown option code received\n"));
@@ -1182,7 +1192,12 @@ int main(int argc, char *argv[])
#ifdef HAVE_GTK
if(gui)
{
- if(gui::main(argc, argv))
+ if(use_new_gui)
+ {
+ if(gui::init(argc, argv))
+ return 0;
+ }
+ else if(gui::main(argc, argv))
return 0;
// Otherwise, fall back to trying to start a curses interface
// (assume that we can't contact the X server, or maybe that we