File: CardBox.h

package info (click to toggle)
granule 1.4.0-7-9
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster
  • size: 5,236 kB
  • ctags: 2,144
  • sloc: cpp: 16,030; makefile: 353
file content (237 lines) | stat: -rw-r--r-- 7,160 bytes parent folder | download | duplicates (5)
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// -*- c++ -*-
//------------------------------------------------------------------------------
// $Id: CardBox.h,v 1.37 2008/01/06 16:51:09 vlg Exp $
//------------------------------------------------------------------------------
//                            CardBox.h
//------------------------------------------------------------------------------
//  Copyright (c) 2004-2006 by Vladislav Grinchenko
//
//  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.      
//------------------------------------------------------------------------------
//
// Date   : Sat Apr 17 23:37:11 EDT 2004
//
//------------------------------------------------------------------------------
#ifndef CARD_BOX_H
#define CARD_BOX_H

#ifdef HAVE_CONFIG_H
#    include "config.h"
#endif

#include <vector>

#include <gdkmm/pixbuf.h>
#include <gdkmm/image.h>
#include <gtkmm/box.h>
#include <gtkmm/label.h>

#include "Granule-main.h"
#include "CardDeck.h"
#include "DeckPlayer.h"
#include "VDeck.h"
#include "ScheduleDB.h"

class Deck;
class VCard;
class MainWindow;

/**
 * @class CardBox
 *
 * CardBox is a GUI tray that initially holds all 5 rows of widgets that 
 * graphically represent card boxes (CardBoxUI). 
 *
 * Each box is filled with a CardDeck that contains a list of references 
 * to the real cards. Thus CardBox is in essence a DeckList of virtual decks.
 *
 * It is responsible for loading and saving the card file as requested 
 * by MainWindow.
 */

class CardBox : public Gtk::HBox
{
public:
	typedef Glib::RefPtr<Gdk::Pixbuf> pixbuf_ref_type;

	typedef std::vector<CardDeck*> cardbox_collection;
	typedef cardbox_collection::iterator cardbox_iterator;

	typedef std::vector<DeckPlayer*> deckplayer_collection;
	typedef deckplayer_collection::iterator deckplayer_iterator;

public:
	CardBox (MainWindow& mwin_);
	~CardBox ();

	void new_file ();
	int  load (const string& fname_);
	int  save ();
	int  save_as (const string& fname_);
	void close ();				// Clean up internals

	void play_deck (int idx_);

	void add_deck_to_box  (int idx_, Deck* from_deck_);
	int  add_cards_to_box (std::vector<CardRef*>& cardref_list_);

	/** Move card to the new box. The movement depends
	 *  on the quality of answer. The source information is
	 *  required to adjust the expiration lights, etc.
	 */
	void move_card_to_box (VDeck::cardlist_iterator card_ref_, 
						   int from_deck_, 
						   AnswerQuality answer_quality_);

	bool play_in_box_cb (GdkEventButton* event, int idx_);

	void on_deck_dropped_cb (const Glib::RefPtr<Gdk::DragContext>& context_,
							 int drop_x_coordinate_,
							 int drop_y_coordinate_,
							 const Gtk::SelectionData& selection_data_,
							 guint type_id_,
							 guint drop_timestamp_,
							 int card_deck_index_);

	std::string get_fname () const { return m_fname; }

	/** Some preferences might have changed. 
	 *	Ask each opened DeckPlayer repaint itself according
	 *  to the new configuration.
	 */
	void repaint_deck_players ();

	void export_sound_bits (const std::string& path_);
	void mark_as_modified ();

	/// Reposition cards according to the new scheduling policy.
	void normalize_cards ();

	/** Hide all DrawerUIs that are beyond the current capacity.
	 */
	void mask_out_unused_boxes ();

	/// Return reference to ScheduleDB
	ScheduleDB& sched_db () { return m_sched_db; }

	/** The capacity has changed. 
	 *  Redestribute the cards accordingly.
	 */
	void adjust_cardbox_tray ();

	/** The EFactor has changed. Although, it is not clear
	 *  what to do, we reset EFactor of each CardRef to 
	 *  the new value. Otherwise, cards might not get evenly
	 *  distributed in the CardBox.
	 */
	void adjust_efactor ();

private:
	/** @class DrawerUI
	 *
	 *  Graphical representation of CardBox status. This includes the 
	 *  Box itself along with color light, and counts of expired and
	 *  total cards in the Box.
	 */
	class DrawerUI 
	{
	public:
		DrawerUI (pixbuf_ref_type drawer_empty_,
				   pixbuf_ref_type grey_light_);

		void reset_counts ();
		void add_one () { m_expired_count++; }

	public:
		Gtk::Image*    m_sched_light;  // Light button to indicate % of overdue 
		Gtk::Label*    m_sched_count;   // How many cards are overdue
		Gtk::VBox*     m_sched_vbox;    // Vbox to hold scheduling widgets
		Gtk::Image*    m_box_pic;       // Image of the box with(out) cards
		Gtk::EventBox* m_evtbox;        // EventBox that holds m_box_pic
		Gtk::Label*    m_total_count_label; // Number of cards in the cardbox
		int            m_expired_count;     // Count of cards that have expired
		bool           m_showed_exp_dialog; // Shown notification dialog once
	};

	typedef std::vector<DrawerUI> drawer_ui_collection;
	typedef drawer_ui_collection::iterator drawer_ui_iterator;

private:
	int  parse_xml_tree (xmlDocPtr parser_, string error_msg_);
	void update_count   (int idx_);

	/** Remove duplicates across all CardDecks if enabled in
		preferences.
	*/
	void remove_all_duplicates (int idx_);

	/** Search for CardRef in all CardDecks.
	 */
	bool find_in_all_carddecks (CardRef* card_ref_);

	/** Change color of expiration light.
	 *  @return smart pointer to the new color.
	 */
	Glib::RefPtr<Gdk::Pixbuf> set_expiration_light (int idx_);

	/// Show hidden DrawerUI
	void expose_hidden_box (int idx_);

private:
	MainWindow& m_mwin;

	/** GUI Representation of the Drawer that displays
	 *  expiration light, total card count, and picture of the drawer.
	 *  Because DrawerUI objects are hosted in Gtk::Table, maximum
	 *  number is allocated at startup, and those not used are hidden().
	 */
	drawer_ui_collection m_drawer_ui;

	Glib::RefPtr<Gdk::Pixbuf> m_drawer_empty;
	Glib::RefPtr<Gdk::Pixbuf> m_drawer_one;
	Glib::RefPtr<Gdk::Pixbuf> m_drawer_many;

	Glib::RefPtr<Gdk::Pixbuf> m_sched_green;
	Glib::RefPtr<Gdk::Pixbuf> m_sched_grey;
	Glib::RefPtr<Gdk::Pixbuf> m_sched_red;
	Glib::RefPtr<Gdk::Pixbuf> m_sched_yellow;

	/** Name of the XML file to load. When m_fname is empty, 
	 *  no file is loaded.
	 */
	string m_fname;

	/// Schedule configuration
	ScheduleDB  m_sched_db;

	/** A collection of CardDecks hosted by CardBox. 
	 *  Each CardDeck is a collection of virtual cards (CardRefs)
	 *  that point to the real cards in real decks. 
	 *  Depending on the 'capacity' configuration of Schedule,
	 *  the number can grow or shrink in the interval [5; 30]
	 */
	cardbox_collection m_card_deck;

	/** Each DeckPlayer is a card player of a corresponding CardDeck.
	 *  Depending on the 'capacity' configuration of Schedule,
	 *  the number can grow or shrink in the interval [5; 30], 
	 *  but it always kept in sync with the CardDeck collection.
	 */
	deckplayer_collection m_deck_player;
};

/*=-----------------------------------------------------------------------------
 *  Inlines
 *=-----------------------------------------------------------------------------
 */
inline CardBox::
~CardBox ()
{
	trace_with_mask("CardBox::~CardBox",GUITRACE);
}


#endif /* CARD_BOX_H */