1 /***************************************************************************
2     Copyright (C) 2001-2009 Robby Stephenson <robby@periapsis.org>
3     Copyright (C) 2011 Pedro Miguel Carvalho <kde@pmc.com.pt>
4  ***************************************************************************/
5 
6 /***************************************************************************
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or         *
9  *   modify it under the terms of the GNU General Public License as        *
10  *   published by the Free Software Foundation; either version 2 of        *
11  *   the License or (at your option) version 3 or any later version        *
12  *   accepted by the membership of KDE e.V. (or its successor approved     *
13  *   by the membership of KDE e.V.), which shall act as a proxy            *
14  *   defined in Section 14 of version 3 of the license.                    *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
23  *                                                                         *
24  ***************************************************************************/
25 
26 #ifndef TELLICO_MAINWINDOW_H
27 #define TELLICO_MAINWINDOW_H
28 
29 #include <config.h>
30 
31 #include "translators/translators.h"
32 #include "datavectors.h"
33 
34 #include <KXmlGuiWindow>
35 
36 #include <QUrl>
37 #include <QList>
38 
39 class KToolBar;
40 class QAction;
41 class KSelectAction;
42 class KToggleAction;
43 class KDualAction;
44 class KRecentFilesAction;
45 class KActionMenu;
46 
47 class QCloseEvent;
48 class QDockWidget;
49 class QSignalMapper;
50 
51 namespace Tellico {
52 // forward declarations
53   namespace GUI {
54     class LineEdit;
55     class TabWidget;
56     class DockWidget;
57   }
58   class Controller;
59   class ViewStack;
60   class DetailedListView;
61   class EntryIconView;
62   class EntryView;
63   class FilterDialog;
64   class EntryEditDialog;
65   class GroupView;
66   class FilterView;
67   class LoanView;
68   class ConfigDialog;
69   class CollectionFieldsDialog;
70   class StringMapDialog;
71   class BibtexKeyDialog;
72   class EntryItem;
73   class FetchDialog;
74   class ReportDialog;
75   class StatusBar;
76   class DropHandler;
77 
78 /**
79  * The base class for Tellico application windows. It sets up the main
80  * window and reads the config file as well as providing a menubar, toolbar
81  * and statusbar. Tellico reimplements the methods that KMainWindow provides
82  * for main window handling and supports full session management as well as
83  * using QActions.
84  *
85  * @author Robby Stephenson
86  */
87 class MainWindow : public KXmlGuiWindow {
88 Q_OBJECT
89 
90 friend class Controller;
91 friend class DropHandler;
92 
93 public:
94   /**
95    * The main window constructor, calls all init functions to create the application.
96    */
97   MainWindow(QWidget* parent=nullptr);
98   ~MainWindow();
99 
100   /**
101    * Opens the initial file.
102    *
103    * @param nofile If true, even if the config option to reopen last file is set, no file is opened
104    */
105   void initFileOpen(bool nofile);
106   /**
107    * Saves the document
108    *
109    * @return Returns @p true if successful
110    */
111   bool fileSave();
112   /**
113    * Saves a document by a new filename
114    *
115    * @return Returns @p true if successful
116    */
117   bool fileSaveAs();
118   /**
119    * @return Returns whether the current collection is still the non-saved default one
120    */
isNewDocument()121   bool isNewDocument() const { return m_newDocument; }
122   /**
123    * Used by main() and DBUS to import file.
124    *
125    * @param format The file format
126    * @param url The url
127    */
128   virtual bool importFile(Import::Format format, const QUrl& url, Import::Action action);
129   /**
130    * Used by DBUS to export to a file.
131    */
132   virtual bool exportCollection(Export::Format format, const QUrl& url, bool filtered);
133   /**
134    * Used by DBUS
135    */
136   virtual void openFile(const QString& file);
137   virtual void setFilter(const QString& text);
138   virtual bool showEntry(Data::ID id);
139 
140   bool eventFilter(QObject* watched, QEvent* event) Q_DECL_OVERRIDE;
141 
142 public Q_SLOTS:
143   /**
144    * Initializes some stuff after the object is created.
145    */
146   void slotInit();
147   /**
148    * Cleans up everything and then opens a new document.
149    *
150    * @param type Type of collection to add
151    */
152   void slotFileNew(int type);
153   /**
154    * Opens a file and loads it into the document
155    */
156   void slotFileOpen();
157   /**
158    * Opens a file by URL and loads it into the document
159    *
160    * @param url The url to open
161    */
162   void slotFileOpen(const QUrl& url);
163   /**
164    * Opens a file from the recent files menu
165    *
166    * @param url The url sent by the RecentFilesAction
167    */
168   void slotFileOpenRecent(const QUrl& url);
169   /**
170    * Saves the document
171    */
172   void slotFileSave();
173   /**
174    * Saves a document by a new filename
175    */
176   void slotFileSaveAs();
177   /**
178    * Prints the current document.
179    */
180   void slotFilePrint();
181   void slotFilePrintPreview();
182   /**
183    * Quits the application.
184    */
185   void slotFileQuit();
186   /**
187    * Puts the marked text/object into the clipboard and removes it from the document.
188    */
189   void slotEditCut();
190   /*
191    * Puts the marked text/object into the clipboard.
192    */
193   void slotEditCopy();
194   /**
195    * Pastes the clipboard into the document.
196    */
197   void slotEditPaste();
198   /**
199    * Selects all the entries in the collection.
200    */
201   void slotEditSelectAll();
202   /**
203    * Deselects all the entries in the collection.
204    */
205   void slotEditDeselect();
206   /**
207    * Toggles the edit widget.
208    */
209   void slotToggleEntryEditor();
210   /**
211    * Shows the configuration dialog for the application.
212    */
213   void slotShowConfigDialog();
214   /**
215    * Hides the configuration dialog for the application.
216    */
217   void slotHideConfigDialog();
218   /**
219    * Shows the fetch dialog.
220    */
221   void slotShowFetchDialog();
222   /**
223    * Hides the fetch dialog.
224    */
225   void slotHideFetchDialog();
226   /**
227    * Changes the statusbar contents for the standard label permanently,
228    * used to indicate current actions being made.
229    *
230    * @param text The text that is displayed in the statusbar
231    */
232   void slotStatusMsg(const QString& text);
233   void slotClearStatus();
234   /**
235    * Updates the entry count in the status bar.
236    */
237   void slotEntryCount();
238   /**
239    * Handles updating everything when the configuration is changed
240    * via the configuration dialog. This slot is called when the OK or Apply
241    * button is clicked in the dialog
242    */
243   void slotHandleConfigChange();
244   /**
245    * Changes the grouping of the entries in the @ref GroupView. The current value
246    * of the combobox in the toolbar is used.
247    */
248   void slotChangeGrouping();
249   /**
250    * Imports data.
251    *
252    * @param format The import format
253    */
254   void slotFileImport(int format);
255   /**
256    * Exports the current document.
257    *
258    * @param format The export format
259    */
260   void slotFileExport(int format);
261   /**
262    * Shows the filter dialog for the application.
263    */
264   void slotShowFilterDialog();
265   /**
266    * Hides the filter dialog for the application.
267    */
268   void slotHideFilterDialog();
269   /**
270    * Shows the collection properties dialog for the application.
271    */
272   void slotShowCollectionFieldsDialog();
273   /**
274    * Hides the collection properties dialog for the application.
275    */
276   void slotHideCollectionFieldsDialog();
277   /**
278    * Shows the "Tip of the Day" dialog.
279    *
280    * @param force Whether the configuration setting should be ignored
281    */
282   void slotShowTipOfDay(bool force=true);
283   /**
284    * Shows the string macro editor dialog for the application.
285    */
286   void slotShowStringMacroDialog();
287   /**
288    * Shows the citation key dialog
289    */
290   void slotShowBibtexKeyDialog();
291   /**
292    * Hides the citation key dialog
293    */
294   void slotHideBibtexKeyDialog();
295   /**
296    * Handle a url that indicates some actino should be taken
297    */
298   void slotURLAction(const QUrl& url);
299 
300 private:
301   /**
302    * Saves the general options like all toolbar positions and status as well as the
303    * geometry and the recent file list to the configuration file.
304    */
305   void saveOptions();
306   /**
307    * Reads the specific options.
308    */
309   void readOptions();
310   /**
311    * Initializes the QActions of the application
312    */
313   void initActions();
314   /**
315    * Sets up the statusbar for the main window by initializing a status label
316    * and inserting a progress bar and entry counter.
317    */
318   void initStatusBar();
319   /**
320    * Initiates the view, setting up all the dock windows and so on.
321    */
322   void initView();
323   /**
324    * Initiates the document.
325    */
326   void initDocument();
327   /**
328    * Initiates all the signal and slot connections between major objects in the view.
329    */
330   void initConnections();
331 
332   bool querySaveModified();
333 
334   /**
335    * Called before the window is closed, either by the user or indirectly by the
336    * session manager.
337    *
338    * The purpose of this function is to prepare the window in a way that it is safe to close it,
339    * i.e. without the user losing some data.
340    * @see KMainWindow::queryClose
341    */
342   bool queryClose() Q_DECL_OVERRIDE;
343   /**
344    * Actual method used when opening a URL. Updating for the list views is turned off
345    * as well as sorting, in order to more quickly load the document.
346    *
347    * @param url The url to open
348    */
349   bool openURL(const QUrl& url);
350   enum PrintAction { Print, PrintPreview };
351   /*
352    * Helper method to handle the printing duties.
353    *
354    * @param html The HTML string representing the doc to print
355    */
356   void doPrint(PrintAction action);
357 
358   void XSLTError();
359   /**
360    * Helper function to activate a slot in the edit widget.
361    * Primarily used for copy, cut, and paste.
362    *
363    * @param slot The slot name
364    */
365   void activateEditSlot(const char* slot);
366   void addFilterView();
367   void addLoanView();
368   void updateCaption(bool modified);
369   void updateCollectionActions();
370   void updateEntrySources();
371 
372 private Q_SLOTS:
373   /**
374    * Updates the actions when a file is opened.
375    */
376   void slotEnableOpenedActions();
377   /**
378    * Updates the save action and the caption when the document is modified.
379    */
380   void slotEnableModifiedActions(bool modified = true);
381   /**
382    * Read the options specific to a collection
383    *
384    * @param coll The collection pointer
385    */
386   void readCollectionOptions(Tellico::Data::CollPtr coll);
387   /**
388    * Saves the options relevant for a collection. I was having problems with the collection
389    * being destructed before I could save info.
390    *
391    * @param coll A pointer to the collection
392    */
393   void saveCollectionOptions(Tellico::Data::CollPtr coll);
394   /**
395    * Queue a filter update. The timer adds a 200 millisecond delay before actually
396    * updating the filter.
397    */
398   void slotQueueFilter();
399   /**
400    * Update the filter to match any field with text. If a non-word character appears, the
401    * text is interpreted as a regexp.
402    */
403   void slotCheckFilterQueue();
404   void slotUpdateFilter(Tellico::FilterPtr filter);
405   /**
406    * Updates the collection toolbar.
407    */
408   void slotUpdateCollectionToolBar(Tellico::Data::CollPtr coll);
409   /**
410    * Make sure the edit dialog is visible and start a new entry.
411    */
412   void slotNewEntry();
413   /**
414    * Handle the entry editor dialog being closed.
415    */
416   void slotEditDialogFinished();
417   /**
418    * Handle the Ok button being clicked in the string macros dialog.
419    */
420   void slotStringMacroDialogFinished(int result=-1);
421   /**
422    * Since I use an application icon in the toolbar, I need to change its size whenever
423    * the toolbar changes mode
424    */
425   void slotUpdateToolbarIcons();
426   /**
427    * Convert current collection to a bibliography.
428    */
429   void slotConvertToBibliography();
430   /**
431    * Send a citation for the selected entries
432    */
433   void slotCiteEntry(int action);
434   /**
435    * Show the entry editor and update menu item.
436    */
437   void slotShowEntryEditor();
438   /**
439    * Show the report window.
440    */
441   void slotShowReportDialog();
442   /**
443    * Show the report window.
444    */
445   void slotHideReportDialog();
446   /**
447    * Focus the filter
448    */
449   void slotGroupLabelActivated();
450   void slotFilterLabelActivated();
451   void slotClearFilter();
452   void slotRenameCollection();
453   void slotImageLocationMismatch();
454   void slotImageLocationChanged();
455   /**
456    * Toggle full screen mode
457    */
458   void slotToggleFullScreen();
459   /**
460    * Toggle menubar visibility
461    */
462   void slotToggleMenuBarVisibility();
463   void slotToggleLayoutLock(bool lock);
464   void slotResetLayout();
465   void guiFactoryReset();
466 
467 private:
468   void importFile(Import::Format format, const QList<QUrl>& kurls);
469   void importText(Import::Format format, const QString& text);
470   bool importCollection(Data::CollPtr coll, Import::Action action);
471 
472   // the reason that I have to keep pointers to all these
473   // is because they get plugged into menus later in Controller
474   KRecentFilesAction* m_fileOpenRecent;
475   QAction* m_fileSave;
476   QAction* m_newEntry;
477   QAction* m_editEntry;
478   QAction* m_copyEntry;
479   QAction* m_deleteEntry;
480   QAction* m_mergeEntry;
481   KActionMenu* m_updateEntryMenu;
482   QAction* m_updateAll;
483   QAction* m_checkInEntry;
484   QAction* m_checkOutEntry;
485   KToggleAction* m_toggleEntryEditor;
486   KDualAction* m_lockLayout;
487 
488   KSelectAction* m_entryGrouping;
489   GUI::LineEdit* m_quickFilter;
490 
491   QMainWindow* m_dummyWindow;
492   GUI::DockWidget* m_groupViewDock;
493   GUI::DockWidget* m_collectionViewDock;
494 
495   Tellico::StatusBar* m_statusBar;
496 
497   DetailedListView* m_detailedView;
498   EntryEditDialog* m_editDialog;
499   GUI::TabWidget* m_viewTabs;
500   GroupView* m_groupView;
501   FilterView* m_filterView;
502   LoanView* m_loanView;
503   EntryView* m_entryView;
504   EntryIconView* m_iconView;
505   ViewStack* m_viewStack;
506   QSignalMapper* m_updateMapper;
507 
508   ConfigDialog* m_configDlg;
509   FilterDialog* m_filterDlg;
510   CollectionFieldsDialog* m_collFieldsDlg;
511   StringMapDialog* m_stringMacroDlg;
512   BibtexKeyDialog* m_bibtexKeyDlg;
513   FetchDialog* m_fetchDlg;
514   ReportDialog* m_reportDlg;
515 
516   QList<QAction*> m_fetchActions;
517 
518   // keep track of the number of queued filter updates
519   uint m_queuedFilters;
520 
521   // keep track whether everything gets initialized
522   bool m_initialized;
523   // need to keep track of whether the current collection has never been saved
524   bool m_newDocument;
525   // Don't queue filter if true
526   bool m_dontQueueFilter;
527   bool m_savingImageLocationChange;
528 };
529 
530 } // end namespace
531 #endif // TELLICO_MAINWINDOW_H
532