1 #ifndef SOFTWARELIST_H
2 #define SOFTWARELIST_H
3 
4 #include <QProcess>
5 #include <QTime>
6 #include <QTimer>
7 #include <QFile>
8 #include <QList>
9 #include <QAction>
10 #include <QTextStream>
11 #include <QXmlDefaultHandler>
12 #include <QMenu>
13 #include <QMovie>
14 #include <QMap>
15 #include <QWidgetAction>
16 
17 #include "ui_softwarelist.h"
18 #include "unzip.h"
19 #include "sevenzipfile.h"
20 #include "swlistexport.h"
21 #include "imagewidget.h"
22 #include "softwarestatefilter.h"
23 
24 class SoftwareListExporter;
25 
26 class SoftwareItem : public QTreeWidgetItem
27 {
28 	public:
SoftwareItem(QTreeWidget * parent)29 		SoftwareItem(QTreeWidget *parent) : QTreeWidgetItem(parent) { ; }
SoftwareItem(QTreeWidgetItem * parent)30 		SoftwareItem(QTreeWidgetItem *parent) : QTreeWidgetItem(parent) { ; }
SoftwareItem(SoftwareItem * parent)31 		SoftwareItem(SoftwareItem *parent) : QTreeWidgetItem((QTreeWidgetItem *)parent) { ; }
32 
33 	protected:
34 		bool operator<(const QTreeWidgetItem &other) const
35 		{
36 			if ( parent() != 0 )
37 				return false;
38 			if ( other.parent() != 0 )
39 				return false;
40 			int col = treeWidget()->sortColumn();
41 			return ( text(col) < other.text(col) );
42 		}
43 };
44 
45 class SoftwareListXmlHandler : public QXmlDefaultHandler
46 {
47 	public:
48 		QTreeWidget *parentTreeWidget;
49 		SoftwareItem *softwareItem;
50 		QString softwareListName;
51 		QString softwareName;
52 		QString softwareSupported;
53 		QString softwareTitle;
54 		QString softwarePublisher;
55 		QString softwareYear;
56 		QString softwarePart;
57 		QString softwareInterface;
58 		QString softwareParentName;
59 		QString currentText;
60 		QStringList compatFilters;
61 		int elementCounter;
62 		bool newSoftwareStates;
63 		bool softwareListHidden;
64 		quint64 numTotal, numCorrect, numMostlyCorrect, numIncorrect, numNotFound, numUnknown;
65 
66 		SoftwareListXmlHandler(QTreeWidget *, QStringList *hiddenLists, bool viewTree = false);
67 		~SoftwareListXmlHandler();
68 
69 		bool startElement(const QString &, const QString &, const QString &, const QXmlAttributes &);
70 		bool endElement(const QString &, const QString &, const QString &);
71 		bool characters(const QString &);
72 
73 		void loadSoftwareStates(QString);
74 
itemList()75 		QList<QTreeWidgetItem *> &itemList() { return m_itemList; }
hideList()76 		QList<QTreeWidgetItem *> &hideList() { return m_hideList; }
viewTree()77 		bool viewTree() { return m_viewTree; }
setViewTree(bool viewTree)78 		void setViewTree(bool viewTree) { m_viewTree = viewTree; }
setHiddenLists(QStringList * hiddenLists)79 		void setHiddenLists(QStringList *hiddenLists) { m_hiddenLists = hiddenLists; }
hiddenLists()80 		QStringList *hiddenLists() { return m_hiddenLists; }
81 
82 	private:
83 		bool m_viewTree;
84 		QList<QTreeWidgetItem *> m_itemList;
85 		QList<QTreeWidgetItem *> m_hideList;
86 		QStringList *m_hiddenLists;
87 };
88 
89 class SoftwareEntryXmlHandler : public QXmlDefaultHandler
90 {
91 	public:
92 		SoftwareItem *parentTreeWidgetItem;
93 		SoftwareItem *partItem;
94 		SoftwareItem *infoItem;
95 		SoftwareItem *requirementItem;
96 		SoftwareItem *compatItem;
97 		SoftwareItem *dataareaItem;
98 		SoftwareItem *romItem;
99 		bool softwareValid;
100 		bool success;
101 		QString softwareName;
102 		int elementCounter;
103 		int animSequenceCounter;
104 		QList<QTreeWidgetItem *> partItems;
105 		QList<QTreeWidgetItem *> infoItems;
106 		QList<QTreeWidgetItem *> requirementItems;
107 		QMap<QTreeWidgetItem *, QComboBox *> comboBoxes;
108 
109 		SoftwareEntryXmlHandler(QTreeWidgetItem *, bool viewTree = false);
110 		~SoftwareEntryXmlHandler();
111 
112 		bool startElement(const QString &, const QString &, const QString &, const QXmlAttributes &);
113 		bool endElement(const QString &, const QString &, const QString &);
114 
viewTree()115 		bool viewTree() { return m_viewTree; }
setViewTree(bool viewTree)116 		void setViewTree(bool viewTree) { m_viewTree = viewTree; }
117 
118 	private:
119 		bool m_viewTree;
120 };
121 
122 // 'floating' snapshot-viewer
123 class SoftwareSnap : public QWidget
124 {
125 	Q_OBJECT
126 
127 	public:
128 		QString listName;
129 		QString entryName;
130 		QPoint position;
131 		QMap<QString, unzFile> snapFileMap;
132 		QMap<QString, SevenZipFile *> snapFileMap7z;
133 #if defined(QMC2_LIBARCHIVE_ENABLED)
134 		QMap<QString, ArchiveFile *> snapArchiveMap;
135 #endif
136 		SoftwareItem *myItem;
137 		QTimer snapForcedResetTimer;
138 		QMenu *contextMenu;
139 		bool ctxMenuRequested;
140 		QString myCacheKey;
141 		QAction *actionCopyPathToClipboard;
142 		int zoom;
143 		QList<int> activeFormats;
144 
145 		SoftwareSnap(QWidget *parent = 0);
146 		~SoftwareSnap();
147 
148 		QString primaryPathFor(QString, QString);
149 		void reloadActiveFormats();
150 		void enableWidgets(bool enable = true);
151 
152 		bool useZip();
153 		bool useSevenZip();
154 		bool useArchive();
155 		void openSource();
156 		void closeSource();
reopenSource()157 		void reopenSource() { closeSource(); openSource(); }
158 
159 	public slots:
160 		void loadImage(bool fromParent = false);
161 		bool replaceImage(QString, QString, QPixmap &);
162 		void resetSnapForced();
163 		void copyToClipboard();
164 		void copyPathToClipboard();
165 		void refresh();
166 		void sevenZipDataReady();
167 		void zoomIn();
168 		void zoomOut();
169 		void resetZoom();
170 
171 	protected:
172 		void paintEvent(QPaintEvent *);
173 		void mousePressEvent(QMouseEvent *);
174 		void enterEvent(QEvent *);
175 		void leaveEvent(QEvent *);
176 		void contextMenuEvent(QContextMenuEvent *);
177 
178 	private:
179 		bool m_async;
180 };
181 
182 class SoftwareList : public QWidget, public Ui::SoftwareList
183 {
184 	Q_OBJECT
185 
186 	public:
187 		bool snapForced;
188 		bool validData;
189 		bool autoSelectSearchItem;
190 		bool autoMounted;
191 		bool interruptLoad;
192 		bool isLoading;
193 		bool isReady;
194 		bool fullyLoaded;
195 		bool loadFinishedFlag;
196 		bool updatingMountDevices;
197 		bool negatedMatch;
198 		bool verifyReadingStdout;
199 		bool searchActive;
200 		bool stopSearch;
201 		int oldMax, oldMin;
202 		int uncommittedSwlDbRows;
203 		QAction *actionAddToFavorites;
204 		QAction *actionRemoveFromFavorites;
205 		QAction *actionSaveFavoritesToFile;
206 		QAction *actionClearSelection;
207 		QAction *actionNegateSearch;
208 		QAction *actionCheckSoftwareStates;
209 		QAction *actionAnalyzeSoftware;
210 		QAction *actionAnalyzeSoftwareList;
211 		QAction *actionAnalyzeSoftwareLists;
212 		QAction *actionRebuildSoftware;
213 		QAction *actionRebuildSoftwareList;
214 		QAction *actionRebuildSoftwareLists;
215 		QAction *analyzeMenuAction;
216 		QAction *rebuildMenuAction;
217 		QAction *viewFlatAction;
218 		QAction *viewTreeAction;
219 		QAction *actionManualOpenInViewer;
220 		QFile softwareStateFile;
221 		QList<QTreeWidgetItem *> softwareListItems, favoritesListItems, searchListItems;
222 		QMenu *softwareListMenu;
223 		QMenu *favoritesOptionsMenu;
224 		QMenu *menuKnownSoftwareHeader;
225 		QMenu *menuFavoriteSoftwareHeader;
226 		QMenu *menuSearchResultsHeader;
227 		QMenu *menuSnapnameAdjustment;
228 		QMenu *menuStatenameAdjustment;
229 		QMenu *menuSoftwareStates;
230 		QMenu *menuSearchOptions;
231 		QMenu *knownSoftwareMenu;
232 		QMenu *toggleListMenu;
233 		QProcess *loadProc;
234 		QProcess *verifyProc;
235 		QString systemName;
236 		QString swlLastLine;
237 		QString softwareListName;
238 		QString oldFmt;
239 		QStringList successfulLookups;
240 		QStringList mountedSoftware;
241 		QStringList swlLines;
242 		QTextStream softwareStateStream;
243 		QTime loadTimer;
244 		QTimer snapTimer;
245 		QTimer searchTimer;
246 		QTimer detailUpdateTimer;
247 		QTreeWidgetItem *currentItem;
248 		QTreeWidgetItem *enteredItem;
249 		quint64 numSoftwareTotal, numSoftwareCorrect, numSoftwareIncorrect, numSoftwareMostlyCorrect, numSoftwareNotFound, numSoftwareUnknown, numSoftwareMatches;
250 		quint64 oldSoftwareCorrect, oldSoftwareIncorrect, oldSoftwareMostlyCorrect, oldSoftwareNotFound, oldSoftwareUnknown;
251 		SoftwareListExporter *exporter;
252 		SoftwareStateFilter *stateFilter;
253 		QWidgetAction *stateFilterAction;
254 		QToolButton *toolBoxButtonKnownSoftware;
255 		QMovie *loadAnimMovie;
256 
257 		static bool isInitialLoad;
258 		static bool swlSupported;
259 		static QString swStatesLastLine;
260 
261 		SoftwareList(QString, QWidget *);
262 		~SoftwareList();
263 
264 		void getXmlData();
265 		QString &getSoftwareListXmlData(QString);
266 		QString &getXmlDataWithEnabledSlots(QStringList);
267 		QString &lookupMountDevice(QString, QString, QStringList *mountList = 0);
268 		QStringList &arguments(QStringList *softwareLists = 0, QStringList *softwareNames = 0);
269 		QString softwareStatus(QString, QString, bool translated = false);
270 		QString &status(SoftwareListXmlHandler *handler = 0);
271 
viewTree()272 		bool viewTree() { return m_viewTree; }
setViewTree(bool viewTree)273 		void setViewTree(bool viewTree) { m_viewTree = viewTree; }
274 
275 		void addMenuSectionHeader(QMenu *menu, QString text);
276 
277 	signals:
278 		void loadFinished(bool);
279 
280 	public slots:
281 		bool load();
282 		bool save();
283 		void updateMountDevices();
284 		void checkSoftwareStates();
285 		void updateStats(SoftwareListXmlHandler *handler = 0);
286 		void loadTree();
287 		void scrollToItem(const QString &listName, const QString &softwareName);
288 		void checkSoftwareManualAvailability();
289 
290 		// auto-connected callback functions
291 		void on_toolButtonReload_clicked(bool);
292 		void on_toolButtonExport_clicked(bool);
293 		void on_toolButtonAddToFavorites_clicked(bool);
294 		void on_toolButtonToggleSoftwareInfo_clicked(bool);
295 		void on_toolButtonCompatFilterToggle_clicked(bool);
296 		void on_toolButtonToggleSnapnameAdjustment_clicked(bool);
297 		void on_toolButtonToggleStatenameAdjustment_clicked(bool);
298 		void on_toolButtonRemoveFromFavorites_clicked(bool);
299 		void on_toolButtonPlay_clicked(bool);
300 		void on_toolButtonPlayEmbedded_clicked(bool);
301 		void on_treeWidgetKnownSoftware_itemSelectionChanged();
302 		void on_treeWidgetKnownSoftware_customContextMenuRequested(const QPoint &);
303 		void on_treeWidgetKnownSoftware_itemEntered(QTreeWidgetItem *, int);
304 		void on_treeWidgetKnownSoftware_itemActivated(QTreeWidgetItem *, int);
305 		void on_treeWidgetKnownSoftware_itemDoubleClicked(QTreeWidgetItem *item, int column);
306 		void on_treeWidgetKnownSoftware_itemExpanded(QTreeWidgetItem *);
on_treeWidgetKnownSoftware_itemClicked(QTreeWidgetItem *,int)307 		void on_treeWidgetKnownSoftware_itemClicked(QTreeWidgetItem *, int) { on_treeWidgetKnownSoftware_itemSelectionChanged(); }
308 		void on_treeWidgetKnownSoftwareTree_itemSelectionChanged();
309 		void on_treeWidgetKnownSoftwareTree_customContextMenuRequested(const QPoint &);
310 		void on_treeWidgetKnownSoftwareTree_itemEntered(QTreeWidgetItem *, int);
311 		void on_treeWidgetKnownSoftwareTree_itemActivated(QTreeWidgetItem *, int);
312 		void on_treeWidgetKnownSoftwareTree_itemDoubleClicked(QTreeWidgetItem *item, int column);
313 		void on_treeWidgetKnownSoftwareTree_itemExpanded(QTreeWidgetItem *);
on_treeWidgetKnownSoftwareTree_itemClicked(QTreeWidgetItem *,int)314 		void on_treeWidgetKnownSoftwareTree_itemClicked(QTreeWidgetItem *, int) { on_treeWidgetKnownSoftwareTree_itemSelectionChanged(); }
315 		void on_treeWidgetFavoriteSoftware_itemSelectionChanged();
316 		void on_treeWidgetFavoriteSoftware_customContextMenuRequested(const QPoint &);
317 		void on_treeWidgetFavoriteSoftware_itemEntered(QTreeWidgetItem *, int);
318 		void on_treeWidgetFavoriteSoftware_itemActivated(QTreeWidgetItem *, int);
319 		void on_treeWidgetFavoriteSoftware_itemDoubleClicked(QTreeWidgetItem *item, int column);
320 		void on_treeWidgetFavoriteSoftware_itemExpanded(QTreeWidgetItem *);
on_treeWidgetFavoriteSoftware_itemClicked(QTreeWidgetItem *,int)321 		void on_treeWidgetFavoriteSoftware_itemClicked(QTreeWidgetItem *, int) { on_treeWidgetFavoriteSoftware_itemSelectionChanged(); }
322 		void on_treeWidgetSearchResults_itemSelectionChanged();
323 		void on_treeWidgetSearchResults_customContextMenuRequested(const QPoint &);
324 		void on_treeWidgetSearchResults_itemEntered(QTreeWidgetItem *, int);
325 		void on_treeWidgetSearchResults_itemActivated(QTreeWidgetItem *, int);
326 		void on_treeWidgetSearchResults_itemDoubleClicked(QTreeWidgetItem *item, int column);
327 		void on_treeWidgetSearchResults_itemExpanded(QTreeWidgetItem *);
on_treeWidgetSearchResults_itemClicked(QTreeWidgetItem *,int)328 		void on_treeWidgetSearchResults_itemClicked(QTreeWidgetItem *, int) { on_treeWidgetSearchResults_itemSelectionChanged(); }
329 		void on_comboBoxSearch_editTextChanged(const QString &);
330 		void on_comboBoxSearch_activated(const QString &);
331 		void on_comboBoxDeviceConfiguration_currentIndexChanged(int);
332 		void on_toolBoxSoftwareList_currentChanged(int);
333 		void on_toolButtonSoftwareStates_toggled(bool);
334 		void on_stackedWidgetKnownSoftware_currentChanged(int);
335 		void on_toolButtonManualOpenInViewer_clicked();
336 
337 		// process management
338 		void loadStarted();
339 		void loadFinished(int, QProcess::ExitStatus);
340 		void loadReadyReadStandardOutput();
341 		void loadReadyReadStandardError();
342 		void loadError(QProcess::ProcessError);
343 		void verifyStarted();
344 		void verifyFinished(int, QProcess::ExitStatus);
345 		void verifyReadyReadStandardOutput();
346 		void verifyReadyReadStandardError();
347 		void verifyError(QProcess::ProcessError);
348 
349 		// other
350 		void treeWidgetKnownSoftware_headerSectionClicked(int);
351 		void treeWidgetKnownSoftwareTree_headerSectionClicked(int);
352 		void treeWidgetFavoriteSoftware_headerSectionClicked(int);
353 		void treeWidgetSearchResults_headerSectionClicked(int);
addToFavorites()354 		void addToFavorites() { on_toolButtonAddToFavorites_clicked(false); }
removeFromFavorites()355 		void removeFromFavorites() { on_toolButtonRemoveFromFavorites_clicked(false); }
356 		void analyzeSoftware();
357 		void analyzeSoftwareList();
358 		void analyzeSoftwareLists();
playActivated()359 		void playActivated() { on_toolButtonPlay_clicked(false); }
playEmbeddedActivated()360 		void playEmbeddedActivated() { on_toolButtonPlayEmbedded_clicked(false); }
361 		void cancelSoftwareSnap();
362 		void comboBoxSearch_editTextChanged_delayed();
363 		void checkMountDeviceSelection();
364 		void loadFavoritesFromFile();
365 		void saveFavoritesToFile();
366 		void checkSoftwareSnap();
367 		void updateDetail();
368 		void adjustSnapnamePattern();
369 		void adjustStatenamePattern();
370 		void clearSoftwareSelection();
371 		void negateSearchTriggered(bool);
372 		void rebuildSoftware();
373 		void rebuildSoftwareList();
374 		void rebuildSoftwareLists();
375 		void updateRebuildSoftwareMenuVisibility();
376 		void analyzeSoftwareMenu_aboutToShow();
377 		void rebuildSoftwareMenu_aboutToShow();
378 		void actionViewFlat_triggered();
379 		void actionViewTree_triggered();
380 		void toggleSoftwareList();
381 		void showAllSoftwareLists();
382 		void showOnlyThisSoftwareList();
383 		void showAllExceptThisSoftwareList();
384 
385 		// callbacks for software-list header context menu requests
386 		void treeWidgetKnownSoftwareHeader_customContextMenuRequested(const QPoint &);
387 		void treeWidgetKnownSoftwareTreeHeader_customContextMenuRequested(const QPoint &);
388 		void actionKnownSoftwareHeader_triggered();
389 		void treeWidgetFavoriteSoftwareHeader_customContextMenuRequested(const QPoint &);
390 		void actionFavoriteSoftwareHeader_triggered();
391 		void treeWidgetSearchResultsHeader_customContextMenuRequested(const QPoint &);
392 		void actionSearchResultsHeader_triggered();
393 
394 	protected:
395 		void mouseMoveEvent(QMouseEvent *);
396 		void leaveEvent(QEvent *);
397 
398 	private:
399 		bool m_viewTree;
400 		QString m_trL, m_trC, m_trM, m_trI, m_trN, m_trU, m_trS;
401 		QString m_statusString;
402 		QString m_selectedSoftwareList, m_selectedSoftwareName;
403 };
404 
405 #endif
406