summaryrefslogtreecommitdiff
path: root/src/menu_tree.h
blob: d1c9682c2bd91d1dc6c2b8e48dbe4946aa10ee6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// menu_tree.h                                      -*-c++-*-
//
//   Copyright (C) 2005, 2007-2008 Daniel Burrows
//
//   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 MENU_TREE
#define MENU_TREE

#include "menu_redirect.h"

#include <cwidget/widgets/editline.h>

#include <cwidget/widgets/tree.h>

#include <generic/apt/matching/pattern.h>

/** \brief A cwidget::widgets::tree augmented with the ability to act as a menu redirector.
 * 
 *  \file menu_tree.h
 */

class pkg_tree_node;
class solution_item;
class undo_group;

/** A cwidget::widgets::tree that can be generically used as a menu redirector.  All
 *  the menu redirection routines are filled in; case analysis on the
 *  currently selected tree item is used to implement them.  In
 *  addition, the tree will pop up a search dialog in response to
 *  either the Search menu command or the corresponding keybinding.
 *
 *  \todo eliminate some of the dynamic_casting by making
 *  pkg_tree_node and solution_item subclasses of menu_redirect; then
 *  you can just cast the active item to a menu_redirect and proxy for
 *  it.
 */
class menu_tree:public cwidget::widgets::tree, public menu_redirect
{
  /** Proxy the given call to the currently selected item, if it
   *  implements the menu_redirect interface.
   */
  bool proxy_redirect(bool (menu_redirect::*)());

  /** Return the selected node, if any, or \b NULL if no node is selected. */
  pkg_tree_node *pkg_node_selection();

  /** Return the selected solution item, if any, or \b NULL if no
   *  solution is selected.
   */
  solution_item *solution_selection();

  /** A precompiled pattern representing the last search that was performed. */
  cwidget::util::ref_ptr<aptitude::matching::pattern> last_search_pattern;

  /** The string that was compiled to produce the above pattern. */
  std::wstring last_search_term;

  /** If \b true, the last search was a backwards search. */
  bool last_search_backwards;

  /** \b true if an incremental search is in progress. */
  bool doing_incsearch;

  /** The iterator that was selected prior to the incremental search. */
  cwidget::widgets::treeiterator pre_incsearch_selected;

  void do_search(std::wstring s, bool backward);
  void do_incsearch(std::wstring s, bool backward);
  void do_cancel_incsearch();

  /** Execute the given action; this is needed because some "wrapper"
   *  code is used to handle undo and so on.
   */
  bool package_action(void (pkg_tree_node::* action)(undo_group *));

  /** \return \b true if a package or a package version is selected. */
  bool pkg_or_ver_selected();

  static cwidget::widgets::editline::history_list search_history;
protected:
  /** Reset all information about the incremental search.  This must be
   *  performed whenever the root is changed.
   */
  void reset_incsearch();

  menu_tree();
public:
  static cwidget::util::ref_ptr<menu_tree> create()
  {
    cwidget::util::ref_ptr<menu_tree> rval(new menu_tree);
    rval->decref();
    return rval;
  }

  ~menu_tree();

  /** \return \b true iff a pkg_node descendant is currently selected. */
  bool package_enabled();

  /** If a pkg_node is currently selected, execute its "install" operation. */
  bool package_install();

  /** If a pkg_node is currently selected, execute its "remove" operation. */
  bool package_remove();

  /** If a pkg_node is currently selected, execute its "purge" operation. */
  bool package_purge();

  /** If a pkg_node is currently selected, execute its "keep" operation. */
  bool package_keep();

  /** If a pkg_node is currently selected, execute its "hold" operation. */
  bool package_hold();

  /** If a pkg_node is currently selected, execute its "set auto" operation. */
  bool package_mark_auto();

  /** If a pkg_node is currently selected, execute its "set manual" operation. */
  bool package_unmark_auto();

  /** \return \b true if a package or a package version is selected. */
  bool package_forbid_enabled();

  /** If a package or a version is selected, perform a "forbid"
   *  operation on it.
   */
  bool package_forbid();

  /** \return \b true if a package or a package version is selected. */
  bool package_changelog_enabled();

  /** If a package or version is selected, show its changelog. */
  bool package_changelog();

  /** \return \b true if a package or a package version is selected. */
  bool package_information_enabled();

  /** If a package or version is selected, show its information. */
  bool package_information();


  /** If a solution item is selected, toggle whether it is rejected. */
  bool resolver_toggle_rejected();

  /** \return \b true if a solution item is selected. */
  bool resolver_toggle_rejected_enabled();

  /** If a solution item is selected, toggle whether it is approved. */
  bool resolver_toggle_approved();

  /** \return \b true if a solution item is selected. */
  bool resolver_toggle_approved_enabled();

  /** If a solution item is selected, view its target. */
  bool resolver_view_target();

  /** \return \b true if a solution item is selected. */
  bool resolver_view_target_enabled();


  /** \return \b true; all package trees know how to search. */
  bool find_search_enabled();

  /** \return \b true; all package trees know how to search. */
  bool find_search_back_enabled();

  /** Execute the 'search' menu command. */
  bool find_search();

  /** Execute the 'search backwards' menu command. */
  bool find_search_back();

  /** \return \b true if there is a "previous search". */
  bool find_research_enabled();

  /** Execute the 're-search' menu command. */
  bool find_research();

  /** \return \b true if there is a "previous search". */
  bool find_repeat_search_back_enabled();

  /** Execute the 'repeat search in opposite direction' menu command. */
  bool find_repeat_search_back();

  /** \return \b false. */
  bool find_limit_enabled();

  /** Does nothing. */
  bool find_limit();

  /** \return \b false. */
  bool find_reset_limit_enabled();

  /** Does nothing. */
  bool find_reset_limit();

  /** \return \b true if this view is active. */
  bool find_broken_enabled();

  /** Find the next broken package (searches for '~b'). */
  bool find_broken();

  bool handle_key(const cwidget::config::key &k);
};

typedef cwidget::util::ref_ptr<menu_tree> menu_tree_ref;

#endif