1 #ifndef RESOURCEMANAGER_H
2 #define RESOURCEMANAGER_H
3 
4 #include <QObject>
5 #include <QString>
6 #include <QImage>
7 #include <QThread>
8 #include <QMutex>
9 #include <QSemaphore>
10 #if QT_VERSION >= 0x050000
11 #	include <poppler-qt5.h>
12 #else
13 #	include <poppler-qt4.h>
14 #endif
15 #include <list>
16 #include <set>
17 
18 
19 class ResourceManager;
20 class Canvas;
21 class KPage;
22 class Worker;
23 class Viewer;
24 class QSocketNotifier;
25 class QDomDocument;
26 class SelectionLine;
27 
28 
29 class Request {
30 public:
31 	Request(int width, int index);
32 
33 	int get_lowest_index();
34 	bool has_index(int index);
35 	bool remove_index_ok(int index);
36 	void update(int width, int index);
37 
38 	int width[3];
39 };
40 
41 
42 class ResourceManager : public QObject {
43 	Q_OBJECT
44 
45 public:
46 	ResourceManager(const QString &file, Viewer *v);
47 	~ResourceManager();
48 
49 	void load(const QString &file, const QByteArray &password);
50 
51 	// document opened correctly?
52 	bool is_valid() const;
53 	bool is_locked() const;
54 
55 	const QString &get_file() const;
56 	void set_file(const QString &new_file);
57 	// page (meta)data
58 	const KPage *get_page(int page, int newWidth, int index);
59 //	QString get_page_label(int page) const;
60 	float get_page_width(int page, bool rotated = true) const;
61 	float get_page_height(int page, bool rotated = true) const;
62 	float get_page_aspect(int page, bool rotated = true) const;
63 	float get_min_aspect(bool rotated = true) const;
64 	float get_max_aspect(bool rotated = true) const;
65 	int get_page_count() const;
66 	const QList<Poppler::Link *> *get_links(int page);
67 	const QList<SelectionLine *> *get_text(int page);
68 	QDomDocument *get_toc() const;
69 
70 	int get_rotation() const;
71 	void rotate(int value, bool relative = true);
72 	void unlock_page(int page) const;
73 	void invert_colors();
74 	bool are_colors_inverted() const;
75 
76 	void collect_garbage(int keep_min, int keep_max, int index);
77 
78 	void connect_canvas() const;
79 
80 	void store_jump(int page);
81 	void clear_jumps();
82 	int jump_back();
83 	int jump_forward();
84 
85 	Poppler::LinkDestination *resolve_link_destination(const QString &name) const;
86 
87 public slots:
88 	void inotify_slot();
89 
90 private:
91 	void enqueue(int page, int width, int index = 0);
92 
93 	void initialize(const QString &file, const QByteArray &password);
94 	void join_threads();
95 	void shutdown();
96 
97 	// sadly, poppler's renderToImage only supports one thread per document
98 	Worker *worker;
99 
100 	Viewer *viewer;
101 
102 	QString file;
103 	Poppler::Document *doc;
104 	QMutex requestMutex;
105 	QMutex garbageMutex;
106 	QSemaphore requestSemaphore;
107 	int center_page;
108 	float max_aspect;
109 	float min_aspect;
110 	std::map<int, Request> requests; // page, index, width
111 	std::set<int> garbage[3];
112 	QMutex link_mutex;
113 
114 	KPage *k_page;
115 
116 	friend class Worker;
117 
118 	int page_count;
119 	int rotation;
120 
121 #ifdef __linux__
122 	int inotify_fd;
123 	int inotify_wd;
124 	QSocketNotifier *i_notifier;
125 #endif
126 
127 	bool inverted_colors;
128 
129 	std::list<int> jumplist;
130 	std::map<int,std::list<int>::iterator> jump_map;
131 	std::list<int>::iterator cur_jump_pos;
132 };
133 
134 #endif
135 
136