1 #include "library_window.h"
2 #include "custom_widgets.h"
3 #include "folder_item.h"
4 
5 #include <QHBoxLayout>
6 #include <QSplitter>
7 #include <QLabel>
8 #include <QDir>
9 #include <QDirModel>
10 #include <QHeaderView>
11 #include <QProcess>
12 #include <QtCore>
13 #include <QFileDialog>
14 #include <QHBoxLayout>
15 #include <QFileIconProvider>
16 #include <QMatrix>
17 #include <QSettings>
18 #include <QHeaderView>
19 
20 #include <algorithm>
21 #include <iterator>
22 #include <typeinfo>
23 #include <thread>
24 #include <future>
25 
26 #include "data_base_management.h"
27 #include "yacreader_global.h"
28 #include "onstart_flow_selection_dialog.h"
29 #include "no_libraries_widget.h"
30 #include "import_widget.h"
31 
32 #include "yacreader_search_line_edit.h"
33 #include "comic_db.h"
34 #include "library_creator.h"
35 #include "package_manager.h"
36 #include "comic_flow_widget.h"
37 #include "create_library_dialog.h"
38 #include "rename_library_dialog.h"
39 #include "properties_dialog.h"
40 #include "export_library_dialog.h"
41 #include "import_library_dialog.h"
42 #include "export_comics_info_dialog.h"
43 #include "import_comics_info_dialog.h"
44 #include "add_library_dialog.h"
45 #include "options_dialog.h"
46 #include "help_about_dialog.h"
47 #include "server_config_dialog.h"
48 #include "comic_model.h"
49 #include "yacreader_tool_bar_stretch.h"
50 #include "yacreader_table_view.h"
51 
52 #include "yacreader_dark_menu.h"
53 #include "yacreader_titled_toolbar.h"
54 #include "yacreader_main_toolbar.h"
55 
56 #include "yacreader_sidebar.h"
57 
58 #include "comics_remover.h"
59 #include "yacreader_library_list_widget.h"
60 #include "yacreader_folders_view.h"
61 
62 #include "comic_vine_dialog.h"
63 #include "api_key_dialog.h"
64 //#include "yacreader_social_dialog.h"
65 
66 #include "comics_view.h"
67 
68 #include "edit_shortcuts_dialog.h"
69 #include "shortcuts_manager.h"
70 
71 #include "comic_files_manager.h"
72 
73 #include "reading_list_model.h"
74 #include "yacreader_reading_lists_view.h"
75 #include "add_label_dialog.h"
76 
77 #include "yacreader_history_controller.h"
78 #include "db_helper.h"
79 
80 #include "reading_list_item.h"
81 #include "opengl_checker.h"
82 
83 #include "yacreader_comics_views_manager.h"
84 
85 #include "trayicon_controller.h"
86 
87 #include "whats_new_controller.h"
88 
89 #include "library_comic_opener.h"
90 
91 #include "QsLog.h"
92 
93 #ifdef Q_OS_WIN
94 #include <shellapi.h>
95 #endif
96 
97 namespace {
98 template<class Remover>
moveAndConnectRemoverToThread(Remover * remover,QThread * thread)99 void moveAndConnectRemoverToThread(Remover *remover, QThread *thread)
100 {
101     Q_ASSERT(remover);
102     Q_ASSERT(thread);
103     remover->moveToThread(thread);
104     QObject::connect(thread, &QThread::started, remover, &Remover::process);
105     QObject::connect(remover, &Remover::finished, remover, &QObject::deleteLater);
106     QObject::connect(remover, &Remover::finished, thread, &QThread::quit);
107     QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
108 }
109 }
110 
111 using namespace YACReader;
112 
LibraryWindow()113 LibraryWindow::LibraryWindow()
114     : QMainWindow(), fullscreen(false), previousFilter(""), fetching(false), status(LibraryWindow::Normal), removeError(false)
115 {
116     createSettings();
117 
118     setupUI();
119 
120     loadLibraries();
121 
122     if (libraries.isEmpty()) {
123         showNoLibrariesWidget();
124     } else {
125         showRootWidget();
126         selectedLibrary->setCurrentIndex(0);
127     }
128 
129     afterLaunchTasks();
130 }
131 
afterLaunchTasks()132 void LibraryWindow::afterLaunchTasks()
133 {
134     if (!libraries.isEmpty()) {
135         WhatsNewController whatsNewController;
136         whatsNewController.showWhatsNewIfNeeded(this);
137     }
138 }
139 
createSettings()140 void LibraryWindow::createSettings()
141 {
142     settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor
143     settings->beginGroup("libraryConfig");
144 }
145 
setupOpenglSetting()146 void LibraryWindow::setupOpenglSetting()
147 {
148 #ifndef NO_OPENGL
149     //FLOW-----------------------------------------------------------------------
150     //---------------------------------------------------------------------------
151 
152     OpenGLChecker openGLChecker;
153     bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion();
154 
155     if (openGLAvailable && !settings->contains(USE_OPEN_GL))
156         settings->setValue(USE_OPEN_GL, 2);
157     else if (!openGLAvailable)
158         settings->setValue(USE_OPEN_GL, 0);
159 #endif
160 }
161 
setupUI()162 void LibraryWindow::setupUI()
163 {
164     setupOpenglSetting();
165 
166     setUnifiedTitleAndToolBarOnMac(true);
167 
168     libraryCreator = new LibraryCreator();
169     packageManager = new PackageManager();
170 
171     historyController = new YACReaderHistoryController(this);
172 
173     createActions();
174     doModels();
175 
176     doDialogs();
177     doLayout();
178     createToolBars();
179     createMenus();
180 
181     navigationController = new YACReaderNavigationController(this, comicsViewsManager);
182 
183     createConnections();
184 
185     setWindowTitle(tr("YACReader Library"));
186 
187     setMinimumSize(800, 480);
188 
189     //restore
190     if (settings->contains(MAIN_WINDOW_GEOMETRY))
191         restoreGeometry(settings->value(MAIN_WINDOW_GEOMETRY).toByteArray());
192     else
193         //if(settings->value(USE_OPEN_GL).toBool() == false)
194         showMaximized();
195 
196     trayIconController = new TrayIconController(settings, this);
197 }
198 
199 /*void LibraryWindow::changeEvent(QEvent *event)
200 {
201     QMainWindow::changeEvent(event);
202 
203     if (event->type() == QEvent::WindowStateChange && isMinimized() &&
204         trayIcon.isVisible()) {
205 #ifdef Q_OS_MACOS
206         OSXHideDockIcon();
207 #endif
208         hide();
209     } else if (event->type() == QEvent::WindowStateChange) {
210 #ifdef Q_OS_MACOS
211         OSXShowDockIcon();
212 #endif
213         show();
214     }
215 }*/
216 
doLayout()217 void LibraryWindow::doLayout()
218 {
219     //LAYOUT ELEMENTS------------------------------------------------------------
220     auto sHorizontal = new QSplitter(Qt::Horizontal); //spliter principal
221 #ifdef Q_OS_MAC
222     sHorizontal->setStyleSheet("QSplitter::handle{image:none;background-color:#B8B8B8;} QSplitter::handle:vertical {height:1px;}");
223 #else
224     sHorizontal->setStyleSheet("QSplitter::handle:vertical {height:4px;}");
225 #endif
226 
227     //TOOLBARS-------------------------------------------------------------------
228     //---------------------------------------------------------------------------
229     editInfoToolBar = new QToolBar();
230     editInfoToolBar->setStyleSheet("QToolBar {border: none;}");
231 
232 #ifdef Q_OS_MAC
233     libraryToolBar = new YACReaderMacOSXToolbar(this);
234 #else
235     libraryToolBar = new YACReaderMainToolBar(this);
236 #endif
237 
238     //FOLDERS FILTER-------------------------------------------------------------
239     //---------------------------------------------------------------------------
240 #ifndef Q_OS_MAC
241     //in MacOSX the searchEdit is created using the toolbar wrapper
242     searchEdit = new YACReaderSearchLineEdit();
243 #endif
244 
245     //SIDEBAR--------------------------------------------------------------------
246     //---------------------------------------------------------------------------
247     sideBar = new YACReaderSideBar;
248 
249     foldersView = sideBar->foldersView;
250     listsView = sideBar->readingListsView;
251     selectedLibrary = sideBar->selectedLibrary;
252 
253     YACReaderTitledToolBar *librariesTitle = sideBar->librariesTitle;
254     YACReaderTitledToolBar *foldersTitle = sideBar->foldersTitle;
255     YACReaderTitledToolBar *readingListsTitle = sideBar->readingListsTitle;
256 
257     librariesTitle->addAction(createLibraryAction);
258     librariesTitle->addAction(openLibraryAction);
259     librariesTitle->addSpacing(3);
260 
261     foldersTitle->addAction(addFolderAction);
262     foldersTitle->addAction(deleteFolderAction);
263     foldersTitle->addSepartor();
264     foldersTitle->addAction(setRootIndexAction);
265     foldersTitle->addAction(expandAllNodesAction);
266     foldersTitle->addAction(colapseAllNodesAction);
267 
268     readingListsTitle->addAction(addReadingListAction);
269     //readingListsTitle->addSepartor();
270     readingListsTitle->addAction(addLabelAction);
271     //readingListsTitle->addSepartor();
272     readingListsTitle->addAction(renameListAction);
273     readingListsTitle->addAction(deleteReadingListAction);
274     readingListsTitle->addSpacing(3);
275 
276     //FINAL LAYOUT-------------------------------------------------------------
277 
278     comicsViewsManager = new YACReaderComicsViewsManager(settings, this);
279 
280     sHorizontal->addWidget(sideBar);
281 #ifndef Q_OS_MAC
282     QVBoxLayout *rightLayout = new QVBoxLayout;
283     rightLayout->addWidget(libraryToolBar);
284     rightLayout->addWidget(comicsViewsManager->containerWidget());
285 
286     rightLayout->setMargin(0);
287     rightLayout->setSpacing(0);
288 
289     QWidget *rightWidget = new QWidget();
290     rightWidget->setLayout(rightLayout);
291 
292     sHorizontal->addWidget(rightWidget);
293 #else
294     sHorizontal->addWidget(comicsViewsManager->containerWidget());
295 #endif
296 
297     sHorizontal->setStretchFactor(0, 0);
298     sHorizontal->setStretchFactor(1, 1);
299     mainWidget = new QStackedWidget(this);
300     mainWidget->addWidget(sHorizontal);
301     setCentralWidget(mainWidget);
302     //FINAL LAYOUT-------------------------------------------------------------
303 
304     //OTHER----------------------------------------------------------------------
305     //---------------------------------------------------------------------------
306     noLibrariesWidget = new NoLibrariesWidget();
307     mainWidget->addWidget(noLibrariesWidget);
308 
309     importWidget = new ImportWidget();
310     mainWidget->addWidget(importWidget);
311 
312     connect(noLibrariesWidget, SIGNAL(createNewLibrary()), this, SLOT(createLibrary()));
313     connect(noLibrariesWidget, SIGNAL(addExistingLibrary()), this, SLOT(showAddLibrary()));
314 
315     //collapsible disabled in macosx (only temporaly)
316 #ifdef Q_OS_MAC
317     sHorizontal->setCollapsible(0, false);
318 #endif
319 }
320 
doDialogs()321 void LibraryWindow::doDialogs()
322 {
323     createLibraryDialog = new CreateLibraryDialog(this);
324     renameLibraryDialog = new RenameLibraryDialog(this);
325     propertiesDialog = new PropertiesDialog(this);
326     comicVineDialog = new ComicVineDialog(this);
327     exportLibraryDialog = new ExportLibraryDialog(this);
328     importLibraryDialog = new ImportLibraryDialog(this);
329     exportComicsInfoDialog = new ExportComicsInfoDialog(this);
330     importComicsInfoDialog = new ImportComicsInfoDialog(this);
331     addLibraryDialog = new AddLibraryDialog(this);
332     optionsDialog = new OptionsDialog(this);
333     optionsDialog->restoreOptions(settings);
334 
335     editShortcutsDialog = new EditShortcutsDialog(this);
336     setUpShortcutsManagement();
337 
338 #ifdef SERVER_RELEASE
339     serverConfigDialog = new ServerConfigDialog(this);
340 #endif
341 
342     had = new HelpAboutDialog(this); //TODO load data.
343     QString sufix = QLocale::system().name();
344     if (QFile(":/files/about_" + sufix + ".html").exists())
345         had->loadAboutInformation(":/files/about_" + sufix + ".html");
346     else
347         had->loadAboutInformation(":/files/about.html");
348 
349     if (QFile(":/files/helpYACReaderLibrary_" + sufix + ".html").exists())
350         had->loadHelp(":/files/helpYACReaderLibrary_" + sufix + ".html");
351     else
352         had->loadHelp(":/files/helpYACReaderLibrary.html");
353 }
354 
setUpShortcutsManagement()355 void LibraryWindow::setUpShortcutsManagement()
356 {
357 
358     QList<QAction *> allActions;
359     QList<QAction *> tmpList;
360 
361     editShortcutsDialog->addActionsGroup("Comics", QIcon(":/images/shortcuts_group_comics.png"),
362                                          tmpList = QList<QAction *>()
363                                                  << openComicAction
364                                                  << saveCoversToAction
365                                                  << setAsReadAction
366                                                  << setAsNonReadAction
367                                                  << setMangaAction
368                                                  << setNormalAction
369                                                  << openContainingFolderComicAction
370                                                  << resetComicRatingAction
371                                                  << selectAllComicsAction
372                                                  << editSelectedComicsAction
373                                                  << asignOrderAction
374                                                  << deleteComicsAction
375                                                  << getInfoAction);
376 
377     allActions << tmpList;
378 
379     editShortcutsDialog->addActionsGroup("Folders", QIcon(":/images/shortcuts_group_folders.png"),
380                                          tmpList = QList<QAction *>()
381                                                  << addFolderAction
382                                                  << deleteFolderAction
383                                                  << setRootIndexAction
384                                                  << expandAllNodesAction
385                                                  << colapseAllNodesAction
386                                                  << openContainingFolderAction
387                                                  << setFolderAsNotCompletedAction
388                                                  << setFolderAsCompletedAction
389                                                  << setFolderAsReadAction
390                                                  << setFolderAsUnreadAction
391                                                  << setFolderAsMangaAction
392                                                  << setFolderAsNormalAction
393                                                  << updateCurrentFolderAction);
394     allActions << tmpList;
395 
396     editShortcutsDialog->addActionsGroup("Lists", QIcon(":/images/shortcuts_group_folders.png"), //TODO change icon
397                                          tmpList = QList<QAction *>()
398                                                  << addReadingListAction
399                                                  << deleteReadingListAction
400                                                  << addLabelAction
401                                                  << renameListAction);
402     allActions << tmpList;
403 
404     editShortcutsDialog->addActionsGroup("General", QIcon(":/images/shortcuts_group_general.png"),
405                                          tmpList = QList<QAction *>()
406                                                  << backAction
407                                                  << forwardAction
408                                                  << focusSearchLineAction
409                                                  << focusComicsViewAction
410                                                  << helpAboutAction
411                                                  << optionsAction
412                                                  << serverConfigAction
413                                                  << showEditShortcutsAction
414                                                  << quitAction);
415 
416     allActions << tmpList;
417 
418     editShortcutsDialog->addActionsGroup("Libraries", QIcon(":/images/shortcuts_group_libraries.png"),
419                                          tmpList = QList<QAction *>()
420                                                  << createLibraryAction
421                                                  << openLibraryAction
422                                                  << exportComicsInfoAction
423                                                  << importComicsInfoAction
424                                                  << exportLibraryAction
425                                                  << importLibraryAction
426                                                  << updateLibraryAction
427                                                  << renameLibraryAction
428                                                  << removeLibraryAction);
429 
430     allActions << tmpList;
431 
432     editShortcutsDialog->addActionsGroup("Visualization", QIcon(":/images/shortcuts_group_visualization.png"),
433                                          tmpList = QList<QAction *>()
434                                                  << showHideMarksAction
435 #ifndef Q_OS_MAC
436                                                  << toggleFullScreenAction
437 #endif
438                                                  << toggleComicsViewAction);
439 
440     allActions << tmpList;
441 
442     ShortcutsManager::getShortcutsManager().registerActions(allActions);
443 }
444 
doModels()445 void LibraryWindow::doModels()
446 {
447     //folders
448     foldersModel = new FolderModel(this);
449     foldersModelProxy = new FolderModelProxy(this);
450     folderQueryResultProcessor.reset(new FolderQueryResultProcessor(foldersModel));
451     //foldersModelProxy->setSourceModel(foldersModel);
452     //comics
453     comicsModel = new ComicModel(this);
454     //lists
455     listsModel = new ReadingListModel(this);
456     listsModelProxy = new ReadingListModelProxy(this);
457 
458     //setSearchFilter(YACReader::NoModifiers, ""); //clear search filter
459 }
460 
createActions()461 void LibraryWindow::createActions()
462 {
463     backAction = new QAction(this);
464     QIcon icoBackButton;
465     icoBackButton.addFile(":/images/main_toolbar/back.png", QSize(), QIcon::Normal);
466     //icoBackButton.addPixmap(QPixmap(":/images/main_toolbar/back_disabled.png"), QIcon::Disabled);
467     backAction->setData(BACK_ACTION_YL);
468     backAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(BACK_ACTION_YL));
469     backAction->setIcon(icoBackButton);
470     backAction->setDisabled(true);
471 
472     forwardAction = new QAction(this);
473     QIcon icoFordwardButton;
474     icoFordwardButton.addFile(":/images/main_toolbar/forward.png", QSize(), QIcon::Normal);
475     //icoFordwardButton.addPixmap(QPixmap(":/images/main_toolbar/forward_disabled.png"), QIcon::Disabled);
476     forwardAction->setData(FORWARD_ACTION_YL);
477     forwardAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FORWARD_ACTION_YL));
478     forwardAction->setIcon(icoFordwardButton);
479     forwardAction->setDisabled(true);
480 
481     createLibraryAction = new QAction(this);
482     createLibraryAction->setToolTip(tr("Create a new library"));
483     createLibraryAction->setData(CREATE_LIBRARY_ACTION_YL);
484     createLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CREATE_LIBRARY_ACTION_YL));
485     createLibraryAction->setIcon(QIcon(":/images/sidebar/newLibraryIcon.png"));
486 
487     openLibraryAction = new QAction(this);
488     openLibraryAction->setToolTip(tr("Open an existing library"));
489     openLibraryAction->setData(OPEN_LIBRARY_ACTION_YL);
490     openLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_LIBRARY_ACTION_YL));
491     openLibraryAction->setIcon(QIcon(":/images/sidebar/openLibraryIcon.png"));
492 
493     exportComicsInfoAction = new QAction(tr("Export comics info"), this);
494     exportComicsInfoAction->setToolTip(tr("Export comics info"));
495     exportComicsInfoAction->setData(EXPORT_COMICS_INFO_ACTION_YL);
496     exportComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_COMICS_INFO_ACTION_YL));
497     exportComicsInfoAction->setIcon(QIcon(":/images/menus_icons/exportComicsInfoIcon.png"));
498 
499     importComicsInfoAction = new QAction(tr("Import comics info"), this);
500     importComicsInfoAction->setToolTip(tr("Import comics info"));
501     importComicsInfoAction->setData(IMPORT_COMICS_INFO_ACTION_YL);
502     importComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_COMICS_INFO_ACTION_YL));
503     importComicsInfoAction->setIcon(QIcon(":/images/menus_icons/importComicsInfoIcon.png"));
504 
505     exportLibraryAction = new QAction(tr("Pack covers"), this);
506     exportLibraryAction->setToolTip(tr("Pack the covers of the selected library"));
507     exportLibraryAction->setData(EXPORT_LIBRARY_ACTION_YL);
508     exportLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_LIBRARY_ACTION_YL));
509     exportLibraryAction->setIcon(QIcon(":/images/menus_icons/exportLibraryIcon.png"));
510 
511     importLibraryAction = new QAction(tr("Unpack covers"), this);
512     importLibraryAction->setToolTip(tr("Unpack a catalog"));
513     importLibraryAction->setData(IMPORT_LIBRARY_ACTION_YL);
514     importLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_LIBRARY_ACTION_YL));
515     importLibraryAction->setIcon(QIcon(":/images/menus_icons/importLibraryIcon.png"));
516 
517     updateLibraryAction = new QAction(tr("Update library"), this);
518     updateLibraryAction->setToolTip(tr("Update current library"));
519     updateLibraryAction->setData(UPDATE_LIBRARY_ACTION_YL);
520     updateLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_LIBRARY_ACTION_YL));
521     updateLibraryAction->setIcon(QIcon(":/images/menus_icons/updateLibraryIcon.png"));
522 
523     renameLibraryAction = new QAction(tr("Rename library"), this);
524     renameLibraryAction->setToolTip(tr("Rename current library"));
525     renameLibraryAction->setData(RENAME_LIBRARY_ACTION_YL);
526     renameLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIBRARY_ACTION_YL));
527     renameLibraryAction->setIcon(QIcon(":/images/menus_icons/editIcon.png"));
528 
529     removeLibraryAction = new QAction(tr("Remove library"), this);
530     removeLibraryAction->setToolTip(tr("Remove current library from your collection"));
531     removeLibraryAction->setData(REMOVE_LIBRARY_ACTION_YL);
532     removeLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_LIBRARY_ACTION_YL));
533     removeLibraryAction->setIcon(QIcon(":/images/menus_icons/removeLibraryIcon.png"));
534 
535     openComicAction = new QAction(tr("Open current comic"), this);
536     openComicAction->setToolTip(tr("Open current comic on YACReader"));
537     openComicAction->setData(OPEN_COMIC_ACTION_YL);
538     openComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_COMIC_ACTION_YL));
539     openComicAction->setIcon(QIcon(":/images/comics_view_toolbar/openInYACReader.png"));
540 
541     saveCoversToAction = new QAction(tr("Save selected covers to..."), this);
542     saveCoversToAction->setToolTip(tr("Save covers of the selected comics as JPG files"));
543     saveCoversToAction->setData(SAVE_COVERS_TO_ACTION_YL);
544     saveCoversToAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_COVERS_TO_ACTION_YL));
545 
546     setAsReadAction = new QAction(tr("Set as read"), this);
547     setAsReadAction->setToolTip(tr("Set comic as read"));
548     setAsReadAction->setData(SET_AS_READ_ACTION_YL);
549     setAsReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_READ_ACTION_YL));
550     setAsReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setReadButton.png"));
551 
552     setAsNonReadAction = new QAction(tr("Set as unread"), this);
553     setAsNonReadAction->setToolTip(tr("Set comic as unread"));
554     setAsNonReadAction->setData(SET_AS_NON_READ_ACTION_YL);
555     setAsNonReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NON_READ_ACTION_YL));
556     setAsNonReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setUnread.png"));
557 
558     setMangaAction = new QAction(tr("Set as manga"), this);
559     setMangaAction->setToolTip(tr("Set issue as manga"));
560     setMangaAction->setData(SET_AS_MANGA_ACTION_YL);
561     setMangaAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_MANGA_ACTION_YL));
562     setMangaAction->setIcon(QIcon(":/images/comics_view_toolbar/setManga.png"));
563 
564     setNormalAction = new QAction(tr("Set as normal"), this);
565     setNormalAction->setToolTip(tr("Set issue as normal"));
566     setNormalAction->setData(SET_AS_NORMAL_ACTION_YL);
567     setNormalAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NORMAL_ACTION_YL));
568     setNormalAction->setIcon(QIcon(":/images/comics_view_toolbar/setNormal.png"));
569 
570     /*setAllAsReadAction = new QAction(tr("Set all as read"),this);
571         setAllAsReadAction->setToolTip(tr("Set all comics as read"));
572         setAllAsReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setAllRead.png"));
573 
574         setAllAsNonReadAction = new QAction(tr("Set all as unread"),this);
575         setAllAsNonReadAction->setToolTip(tr("Set all comics as unread"));
576         setAllAsNonReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setAllUnread.png"));*/
577 
578     showHideMarksAction = new QAction(tr("Show/Hide marks"), this);
579     showHideMarksAction->setToolTip(tr("Show or hide read marks"));
580     showHideMarksAction->setData(SHOW_HIDE_MARKS_ACTION_YL);
581     showHideMarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_MARKS_ACTION_YL));
582     showHideMarksAction->setCheckable(true);
583     showHideMarksAction->setIcon(QIcon(":/images/comics_view_toolbar/showMarks.png"));
584     showHideMarksAction->setChecked(true);
585 #ifndef Q_OS_MAC
586     toggleFullScreenAction = new QAction(tr("Fullscreen mode on/off"), this);
587     toggleFullScreenAction->setToolTip(tr("Fullscreen mode on/off"));
588     toggleFullScreenAction->setData(TOGGLE_FULL_SCREEN_ACTION_YL);
589     toggleFullScreenAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_FULL_SCREEN_ACTION_YL));
590     QIcon icoFullscreenButton;
591     icoFullscreenButton.addPixmap(QPixmap(":/images/main_toolbar/fullscreen.png"), QIcon::Normal);
592     toggleFullScreenAction->setIcon(icoFullscreenButton);
593 #endif
594     helpAboutAction = new QAction(this);
595     helpAboutAction->setToolTip(tr("Help, About YACReader"));
596     helpAboutAction->setData(HELP_ABOUT_ACTION_YL);
597     helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_YL));
598     QIcon icoHelpButton;
599     icoHelpButton.addFile(":/images/main_toolbar/help.png", QSize(), QIcon::Normal);
600     helpAboutAction->setIcon(icoHelpButton);
601 
602     addFolderAction = new QAction(tr("Add new folder"), this);
603     addFolderAction->setData(ADD_FOLDER_ACTION_YL);
604     addFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_FOLDER_ACTION_YL));
605     addFolderAction->setToolTip(tr("Add new folder to the current library"));
606     addFolderAction->setIcon(QIcon(":/images/sidebar/addNew_sidebar.png"));
607 
608     deleteFolderAction = new QAction(tr("Delete folder"), this);
609     deleteFolderAction->setData(REMOVE_FOLDER_ACTION_YL);
610     deleteFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_FOLDER_ACTION_YL));
611     deleteFolderAction->setToolTip(tr("Delete current folder from disk"));
612     deleteFolderAction->setIcon(QIcon(":/images/sidebar/delete_sidebar.png"));
613 
614     setRootIndexAction = new QAction(this);
615     setRootIndexAction->setData(SET_ROOT_INDEX_ACTION_YL);
616     setRootIndexAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_ROOT_INDEX_ACTION_YL));
617     setRootIndexAction->setToolTip(tr("Select root node"));
618     setRootIndexAction->setIcon(QIcon(":/images/sidebar/setRoot.png"));
619 
620     expandAllNodesAction = new QAction(this);
621     expandAllNodesAction->setToolTip(tr("Expand all nodes"));
622     expandAllNodesAction->setData(EXPAND_ALL_NODES_ACTION_YL);
623     expandAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPAND_ALL_NODES_ACTION_YL));
624     expandAllNodesAction->setIcon(QIcon(":/images/sidebar/expand.png"));
625 
626     colapseAllNodesAction = new QAction(this);
627     colapseAllNodesAction->setToolTip(tr("Collapse all nodes"));
628     colapseAllNodesAction->setData(COLAPSE_ALL_NODES_ACTION_YL);
629     colapseAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(COLAPSE_ALL_NODES_ACTION_YL));
630     colapseAllNodesAction->setIcon(QIcon(":/images/sidebar/colapse.png"));
631 
632     optionsAction = new QAction(this);
633     optionsAction->setToolTip(tr("Show options dialog"));
634     optionsAction->setData(OPTIONS_ACTION_YL);
635     optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_YL));
636     QIcon icoSettingsButton;
637     icoSettingsButton.addFile(":/images/main_toolbar/settings.png", QSize(), QIcon::Normal);
638     optionsAction->setIcon(icoSettingsButton);
639 
640     serverConfigAction = new QAction(this);
641     serverConfigAction->setToolTip(tr("Show comics server options dialog"));
642     serverConfigAction->setData(SERVER_CONFIG_ACTION_YL);
643     serverConfigAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SERVER_CONFIG_ACTION_YL));
644     QIcon icoServerButton;
645     icoServerButton.addFile(":/images/main_toolbar/server.png", QSize(), QIcon::Normal);
646     serverConfigAction->setIcon(icoServerButton);
647 
648     toggleComicsViewAction = new QAction(tr("Change between comics views"), this);
649     toggleComicsViewAction->setToolTip(tr("Change between comics views"));
650     QIcon icoViewsButton;
651 
652     if (!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow)
653         icoViewsButton.addFile(":/images/main_toolbar/grid.png", QSize(), QIcon::Normal);
654     else if (settings->value(COMICS_VIEW_STATUS) == Grid)
655         icoViewsButton.addFile(":/images/main_toolbar/info.png", QSize(), QIcon::Normal);
656     else
657         icoViewsButton.addFile(":/images/main_toolbar/flow.png", QSize(), QIcon::Normal);
658 
659     toggleComicsViewAction->setData(TOGGLE_COMICS_VIEW_ACTION_YL);
660     toggleComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_COMICS_VIEW_ACTION_YL));
661     toggleComicsViewAction->setIcon(icoViewsButton);
662     //socialAction = new QAction(this);
663 
664     //----
665 
666     openContainingFolderAction = new QAction(this);
667     openContainingFolderAction->setText(tr("Open folder..."));
668     openContainingFolderAction->setData(OPEN_CONTAINING_FOLDER_ACTION_YL);
669     openContainingFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_ACTION_YL));
670     openContainingFolderAction->setIcon(QIcon(":/images/menus_icons/open.png"));
671 
672     setFolderAsNotCompletedAction = new QAction(this);
673     setFolderAsNotCompletedAction->setText(tr("Set as uncompleted"));
674     setFolderAsNotCompletedAction->setData(SET_FOLDER_AS_NOT_COMPLETED_ACTION_YL);
675     setFolderAsNotCompletedAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_NOT_COMPLETED_ACTION_YL));
676 
677     setFolderAsCompletedAction = new QAction(this);
678     setFolderAsCompletedAction->setText(tr("Set as completed"));
679     setFolderAsCompletedAction->setData(SET_FOLDER_AS_COMPLETED_ACTION_YL);
680     setFolderAsCompletedAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_COMPLETED_ACTION_YL));
681 
682     setFolderAsReadAction = new QAction(this);
683     setFolderAsReadAction->setText(tr("Set as read"));
684     setFolderAsReadAction->setData(SET_FOLDER_AS_READ_ACTION_YL);
685     setFolderAsReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_READ_ACTION_YL));
686 
687     setFolderAsUnreadAction = new QAction(this);
688     setFolderAsUnreadAction->setText(tr("Set as unread"));
689     setFolderAsUnreadAction->setData(SET_FOLDER_AS_UNREAD_ACTION_YL);
690     setFolderAsUnreadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_UNREAD_ACTION_YL));
691 
692     setFolderAsMangaAction = new QAction(this);
693     setFolderAsMangaAction->setText(tr("Set as manga"));
694     setFolderAsMangaAction->setData(SET_FOLDER_AS_MANGA_ACTION_YL);
695     setFolderAsMangaAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_MANGA_ACTION_YL));
696 
697     setFolderAsNormalAction = new QAction(this);
698     setFolderAsNormalAction->setText(tr("Set as comic"));
699     setFolderAsNormalAction->setData(SET_FOLDER_AS_NORMAL_ACTION_YL);
700     setFolderAsNormalAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_NORMAL_ACTION_YL));
701 
702     //----
703 
704     openContainingFolderComicAction = new QAction(this);
705     openContainingFolderComicAction->setText(tr("Open containing folder..."));
706     openContainingFolderComicAction->setData(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL);
707     openContainingFolderComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL));
708     openContainingFolderComicAction->setIcon(QIcon(":/images/menus_icons/open.png"));
709 
710     resetComicRatingAction = new QAction(this);
711     resetComicRatingAction->setText(tr("Reset comic rating"));
712     resetComicRatingAction->setData(RESET_COMIC_RATING_ACTION_YL);
713     resetComicRatingAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RESET_COMIC_RATING_ACTION_YL));
714 
715     //Edit comics actions------------------------------------------------------
716     selectAllComicsAction = new QAction(this);
717     selectAllComicsAction->setText(tr("Select all comics"));
718     selectAllComicsAction->setData(SELECT_ALL_COMICS_ACTION_YL);
719     selectAllComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SELECT_ALL_COMICS_ACTION_YL));
720     selectAllComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/selectAll.png"));
721 
722     editSelectedComicsAction = new QAction(this);
723     editSelectedComicsAction->setText(tr("Edit"));
724     editSelectedComicsAction->setData(EDIT_SELECTED_COMICS_ACTION_YL);
725     editSelectedComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EDIT_SELECTED_COMICS_ACTION_YL));
726     editSelectedComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/editComic.png"));
727 
728     asignOrderAction = new QAction(this);
729     asignOrderAction->setText(tr("Assign current order to comics"));
730     asignOrderAction->setData(ASIGN_ORDER_ACTION_YL);
731     asignOrderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ASIGN_ORDER_ACTION_YL));
732     asignOrderAction->setIcon(QIcon(":/images/comics_view_toolbar/asignNumber.png"));
733 
734     forceCoverExtractedAction = new QAction(this);
735     forceCoverExtractedAction->setText(tr("Update cover"));
736     forceCoverExtractedAction->setData(FORCE_COVER_EXTRACTED_ACTION_YL);
737     forceCoverExtractedAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FORCE_COVER_EXTRACTED_ACTION_YL));
738     forceCoverExtractedAction->setIcon(QIcon(":/images/importCover.png"));
739 
740     deleteComicsAction = new QAction(this);
741     deleteComicsAction->setText(tr("Delete selected comics"));
742     deleteComicsAction->setData(DELETE_COMICS_ACTION_YL);
743     deleteComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DELETE_COMICS_ACTION_YL));
744     deleteComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/trash.png"));
745 
746     getInfoAction = new QAction(this);
747     getInfoAction->setData(GET_INFO_ACTION_YL);
748     getInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GET_INFO_ACTION_YL));
749     getInfoAction->setText(tr("Download tags from Comic Vine"));
750     getInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/getInfo.png"));
751     //-------------------------------------------------------------------------
752 
753     focusSearchLineAction = new QAction(tr("Focus search line"), this);
754     focusSearchLineAction->setData(FOCUS_SEARCH_LINE_ACTION_YL);
755     focusSearchLineAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FOCUS_SEARCH_LINE_ACTION_YL));
756     focusSearchLineAction->setIcon(QIcon(":/images/iconSearch.png"));
757     addAction(focusSearchLineAction);
758 
759     focusComicsViewAction = new QAction(tr("Focus comics view"), this);
760     focusComicsViewAction->setData(FOCUS_COMICS_VIEW_ACTION_YL);
761     focusComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FOCUS_COMICS_VIEW_ACTION_YL));
762     addAction(focusComicsViewAction);
763 
764     showEditShortcutsAction = new QAction(tr("Edit shortcuts"), this);
765     showEditShortcutsAction->setData(SHOW_EDIT_SHORTCUTS_ACTION_YL);
766     showEditShortcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_EDIT_SHORTCUTS_ACTION_YL));
767     showEditShortcutsAction->setShortcutContext(Qt::ApplicationShortcut);
768     addAction(showEditShortcutsAction);
769 
770     quitAction = new QAction(tr("&Quit"), this);
771     quitAction->setIcon(QIcon(":/images/viewer_toolbar/close.png"));
772     quitAction->setData(QUIT_ACTION_YL);
773     quitAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(QUIT_ACTION_YL));
774     // TODO: is `quitAction->setMenuRole(QAction::QuitRole);` useful on macOS?
775     addAction(quitAction);
776 
777     updateFolderAction = new QAction(tr("Update folder"), this);
778     updateFolderAction->setIcon(QIcon(":/images/menus_icons/updateLibraryIcon.png"));
779 
780     updateCurrentFolderAction = new QAction(tr("Update current folder"), this);
781     updateCurrentFolderAction->setData(UPDATE_CURRENT_FOLDER_ACTION_YL);
782     updateCurrentFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_CURRENT_FOLDER_ACTION_YL));
783     updateCurrentFolderAction->setIcon(QIcon(":/images/menus_icons/updateLibraryIcon.png"));
784 
785     addReadingListAction = new QAction(tr("Add new reading list"), this);
786     addReadingListAction->setData(ADD_READING_LIST_ACTION_YL);
787     addReadingListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_READING_LIST_ACTION_YL));
788     addReadingListAction->setToolTip(tr("Add a new reading list to the current library"));
789     addReadingListAction->setIcon(QIcon(":/images/sidebar/addNew_sidebar.png"));
790 
791     deleteReadingListAction = new QAction(tr("Remove reading list"), this);
792     deleteReadingListAction->setData(REMOVE_READING_LIST_ACTION_YL);
793     deleteReadingListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_READING_LIST_ACTION_YL));
794     deleteReadingListAction->setToolTip(tr("Remove current reading list from the library"));
795     deleteReadingListAction->setIcon(QIcon(":/images/sidebar/delete_sidebar.png"));
796 
797     addLabelAction = new QAction(tr("Add new label"), this);
798     addLabelAction->setData(ADD_LABEL_ACTION_YL);
799     addLabelAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_LABEL_ACTION_YL));
800     addLabelAction->setToolTip(tr("Add a new label to this library"));
801     addLabelAction->setIcon(QIcon(":/images/sidebar/addLabelIcon.png"));
802 
803     renameListAction = new QAction(tr("Rename selected list"), this);
804     renameListAction->setData(RENAME_LIST_ACTION_YL);
805     renameListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIST_ACTION_YL));
806     renameListAction->setToolTip(tr("Rename any selected labels or lists"));
807     renameListAction->setIcon(QIcon(":/images/sidebar/renameListIcon.png"));
808 
809     //--
810     addToMenuAction = new QAction(tr("Add to..."), this);
811 
812     addToFavoritesAction = new QAction(tr("Favorites"), this);
813     addToFavoritesAction->setData(ADD_TO_FAVORITES_ACTION_YL);
814     addToFavoritesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_TO_FAVORITES_ACTION_YL));
815     addToFavoritesAction->setToolTip(tr("Add selected comics to favorites list"));
816     addToFavoritesAction->setIcon(QIcon(":/images/lists/default_1.png"));
817 
818     //actions not asigned to any widget
819     this->addAction(saveCoversToAction);
820     this->addAction(openContainingFolderAction);
821     this->addAction(updateCurrentFolderAction);
822     this->addAction(resetComicRatingAction);
823     this->addAction(setFolderAsCompletedAction);
824     this->addAction(setFolderAsNotCompletedAction);
825     this->addAction(setFolderAsReadAction);
826     this->addAction(setFolderAsUnreadAction);
827     this->addAction(setFolderAsMangaAction);
828     this->addAction(setFolderAsNormalAction);
829 #ifndef Q_OS_MAC
830     this->addAction(toggleFullScreenAction);
831 #endif
832 
833     //disable actions
834     disableAllActions();
835 }
disableComicsActions(bool disabled)836 void LibraryWindow::disableComicsActions(bool disabled)
837 {
838     //if there aren't comics, no fullscreen option will be available
839 #ifndef Q_OS_MAC
840     toggleFullScreenAction->setDisabled(disabled);
841 #endif
842     //edit toolbar
843     openComicAction->setDisabled(disabled);
844     editSelectedComicsAction->setDisabled(disabled);
845     selectAllComicsAction->setDisabled(disabled);
846     asignOrderAction->setDisabled(disabled);
847     setAsReadAction->setDisabled(disabled);
848     setAsNonReadAction->setDisabled(disabled);
849     setNormalAction->setDisabled(disabled);
850     setMangaAction->setDisabled(disabled);
851     //setAllAsReadAction->setDisabled(disabled);
852     //setAllAsNonReadAction->setDisabled(disabled);
853     showHideMarksAction->setDisabled(disabled);
854     deleteComicsAction->setDisabled(disabled);
855     //context menu
856     openContainingFolderComicAction->setDisabled(disabled);
857     resetComicRatingAction->setDisabled(disabled);
858 
859     getInfoAction->setDisabled(disabled);
860 
861     updateCurrentFolderAction->setDisabled(disabled);
862 }
disableLibrariesActions(bool disabled)863 void LibraryWindow::disableLibrariesActions(bool disabled)
864 {
865     updateLibraryAction->setDisabled(disabled);
866     renameLibraryAction->setDisabled(disabled);
867     removeLibraryAction->setDisabled(disabled);
868     exportComicsInfoAction->setDisabled(disabled);
869     importComicsInfoAction->setDisabled(disabled);
870     exportLibraryAction->setDisabled(disabled);
871     //importLibraryAction->setDisabled(disabled);
872 }
873 
disableNoUpdatedLibrariesActions(bool disabled)874 void LibraryWindow::disableNoUpdatedLibrariesActions(bool disabled)
875 {
876     updateLibraryAction->setDisabled(disabled);
877     exportComicsInfoAction->setDisabled(disabled);
878     importComicsInfoAction->setDisabled(disabled);
879     exportLibraryAction->setDisabled(disabled);
880 }
881 
disableFoldersActions(bool disabled)882 void LibraryWindow::disableFoldersActions(bool disabled)
883 {
884     setRootIndexAction->setDisabled(disabled);
885     expandAllNodesAction->setDisabled(disabled);
886     colapseAllNodesAction->setDisabled(disabled);
887 
888     openContainingFolderAction->setDisabled(disabled);
889 
890     updateFolderAction->setDisabled(disabled);
891 }
892 
disableAllActions()893 void LibraryWindow::disableAllActions()
894 {
895     disableComicsActions(true);
896     disableLibrariesActions(true);
897     disableFoldersActions(true);
898 }
899 
createToolBars()900 void LibraryWindow::createToolBars()
901 {
902 
903 #ifdef Q_OS_MAC
904     //libraryToolBar->setIconSize(QSize(16,16)); //TODO make icon size dynamic
905 
906     libraryToolBar->addAction(backAction);
907     libraryToolBar->addAction(forwardAction);
908 
909     libraryToolBar->addSpace(10);
910 
911 #ifdef SERVER_RELEASE
912     libraryToolBar->addAction(serverConfigAction);
913 #endif
914     libraryToolBar->addAction(optionsAction);
915     libraryToolBar->addAction(helpAboutAction);
916 
917     libraryToolBar->addSpace(10);
918 
919     libraryToolBar->addAction(toggleComicsViewAction);
920 #ifndef Q_OS_MAC
921     libraryToolBar->addAction(toggleFullScreenAction);
922 #endif
923 
924     libraryToolBar->addStretch();
925 
926     //Native toolbar search edit
927     //libraryToolBar->addWidget(searchEdit);
928     searchEdit = libraryToolBar->addSearchEdit();
929     //connect(libraryToolBar,SIGNAL(searchTextChanged(YACReader::SearchModifiers,QString)),this,SLOT(setSearchFilter(YACReader::SearchModifiers, QString)));
930 
931     //libraryToolBar->setMovable(false);
932 
933     libraryToolBar->attachToWindow(this->windowHandle());
934 
935 #else
936     libraryToolBar->backButton->setDefaultAction(backAction);
937     libraryToolBar->forwardButton->setDefaultAction(forwardAction);
938     libraryToolBar->settingsButton->setDefaultAction(optionsAction);
939     libraryToolBar->serverButton->setDefaultAction(serverConfigAction);
940     libraryToolBar->helpButton->setDefaultAction(helpAboutAction);
941     libraryToolBar->toggleComicsViewButton->setDefaultAction(toggleComicsViewAction);
942     libraryToolBar->fullscreenButton->setDefaultAction(toggleFullScreenAction);
943     libraryToolBar->setSearchWidget(searchEdit);
944 #endif
945 
946     editInfoToolBar->setIconSize(QSize(18, 18));
947     editInfoToolBar->addAction(openComicAction);
948     editInfoToolBar->addSeparator();
949     editInfoToolBar->addAction(editSelectedComicsAction);
950     editInfoToolBar->addAction(getInfoAction);
951     editInfoToolBar->addAction(asignOrderAction);
952 
953     editInfoToolBar->addSeparator();
954 
955     editInfoToolBar->addAction(selectAllComicsAction);
956 
957     editInfoToolBar->addSeparator();
958 
959     editInfoToolBar->addAction(setAsReadAction);
960     //editInfoToolBar->addAction(setAllAsReadAction);
961     editInfoToolBar->addAction(setAsNonReadAction);
962     //editInfoToolBar->addAction(setAllAsNonReadAction);
963 
964     editInfoToolBar->addAction(showHideMarksAction);
965 
966     editInfoToolBar->addSeparator();
967 
968     editInfoToolBar->addAction(setNormalAction);
969     editInfoToolBar->addAction(setMangaAction);
970 
971     editInfoToolBar->addSeparator();
972 
973     editInfoToolBar->addAction(deleteComicsAction);
974 
975     comicsViewsManager->comicsView->setToolBar(editInfoToolBar);
976 }
977 
createMenus()978 void LibraryWindow::createMenus()
979 {
980     foldersView->addAction(addFolderAction);
981     foldersView->addAction(deleteFolderAction);
982     YACReader::addSperator(foldersView);
983 
984     foldersView->addAction(openContainingFolderAction);
985     foldersView->addAction(updateFolderAction);
986     YACReader::addSperator(foldersView);
987 
988     foldersView->addAction(setFolderAsNotCompletedAction);
989     foldersView->addAction(setFolderAsCompletedAction);
990     YACReader::addSperator(foldersView);
991 
992     foldersView->addAction(setFolderAsReadAction);
993     foldersView->addAction(setFolderAsUnreadAction);
994     YACReader::addSperator(foldersView);
995 
996     foldersView->addAction(setFolderAsMangaAction);
997     foldersView->addAction(setFolderAsNormalAction);
998 
999     selectedLibrary->addAction(updateLibraryAction);
1000     selectedLibrary->addAction(renameLibraryAction);
1001     selectedLibrary->addAction(removeLibraryAction);
1002     YACReader::addSperator(selectedLibrary);
1003 
1004     selectedLibrary->addAction(exportComicsInfoAction);
1005     selectedLibrary->addAction(importComicsInfoAction);
1006     YACReader::addSperator(selectedLibrary);
1007 
1008     selectedLibrary->addAction(exportLibraryAction);
1009     selectedLibrary->addAction(importLibraryAction);
1010 
1011 //MacOSX app menus
1012 #ifdef Q_OS_MACX
1013     QMenuBar *menu = this->menuBar();
1014     //about / preferences
1015     //TODO
1016 
1017     //library
1018     QMenu *libraryMenu = new QMenu(tr("Library"));
1019 
1020     libraryMenu->addAction(updateLibraryAction);
1021     libraryMenu->addAction(renameLibraryAction);
1022     libraryMenu->addAction(removeLibraryAction);
1023     libraryMenu->addSeparator();
1024 
1025     libraryMenu->addAction(exportComicsInfoAction);
1026     libraryMenu->addAction(importComicsInfoAction);
1027 
1028     libraryMenu->addSeparator();
1029 
1030     libraryMenu->addAction(exportLibraryAction);
1031     libraryMenu->addAction(importLibraryAction);
1032 
1033     //folder
1034     QMenu *folderMenu = new QMenu(tr("Folder"));
1035     folderMenu->addAction(openContainingFolderAction);
1036     folderMenu->addAction(updateFolderAction);
1037     folderMenu->addSeparator();
1038     folderMenu->addAction(setFolderAsNotCompletedAction);
1039     folderMenu->addAction(setFolderAsCompletedAction);
1040     folderMenu->addSeparator();
1041     folderMenu->addAction(setFolderAsReadAction);
1042     folderMenu->addAction(setFolderAsUnreadAction);
1043     folderMenu->addSeparator();
1044     foldersView->addAction(setFolderAsMangaAction);
1045     foldersView->addAction(setFolderAsNormalAction);
1046 
1047     //comic
1048     QMenu *comicMenu = new QMenu(tr("Comic"));
1049     comicMenu->addAction(openContainingFolderComicAction);
1050     comicMenu->addSeparator();
1051     comicMenu->addAction(resetComicRatingAction);
1052 
1053     menu->addMenu(libraryMenu);
1054     menu->addMenu(folderMenu);
1055     menu->addMenu(comicMenu);
1056 #endif
1057 }
1058 
createConnections()1059 void LibraryWindow::createConnections()
1060 {
1061     //history navigation
1062     connect(backAction, SIGNAL(triggered()), historyController, SLOT(backward()));
1063     connect(forwardAction, SIGNAL(triggered()), historyController, SLOT(forward()));
1064     //--
1065     connect(historyController, SIGNAL(enabledBackward(bool)), backAction, SLOT(setEnabled(bool)));
1066     connect(historyController, SIGNAL(enabledForward(bool)), forwardAction, SLOT(setEnabled(bool)));
1067     //connect(foldersView, SIGNAL(clicked(QModelIndex)), historyController, SLOT(updateHistory(QModelIndex)));
1068 
1069     //libraryCreator connections
1070     connect(createLibraryDialog, SIGNAL(createLibrary(QString, QString, QString)), this, SLOT(create(QString, QString, QString)));
1071     connect(createLibraryDialog, SIGNAL(libraryExists(QString)), this, SLOT(libraryAlreadyExists(QString)));
1072     connect(importComicsInfoDialog, SIGNAL(finished(int)), this, SLOT(reloadCurrentLibrary()));
1073 
1074     //connect(libraryCreator,SIGNAL(coverExtracted(QString)),createLibraryDialog,SLOT(showCurrentFile(QString)));
1075     //connect(libraryCreator,SIGNAL(coverExtracted(QString)),updateLibraryDialog,SLOT(showCurrentFile(QString)));
1076     connect(libraryCreator, SIGNAL(finished()), this, SLOT(showRootWidget()));
1077     connect(libraryCreator, SIGNAL(updated()), this, SLOT(reloadCurrentLibrary()));
1078     connect(libraryCreator, SIGNAL(created()), this, SLOT(openLastCreated()));
1079     //connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(showRootWidget()));
1080     connect(libraryCreator, SIGNAL(updatedCurrentFolder(QModelIndex)), this, SLOT(reloadAfterCopyMove(QModelIndex)));
1081     connect(libraryCreator, SIGNAL(comicAdded(QString, QString)), importWidget, SLOT(newComic(QString, QString)));
1082     //libraryCreator errors
1083     connect(libraryCreator, SIGNAL(failedCreatingDB(QString)), this, SLOT(manageCreatingError(QString)));
1084     connect(libraryCreator, SIGNAL(failedUpdatingDB(QString)), this, SLOT(manageUpdatingError(QString))); //TODO: implement failedUpdatingDB
1085 
1086     //new import widget
1087     connect(importWidget, SIGNAL(stop()), this, SLOT(stopLibraryCreator()));
1088 
1089     //packageManager connections
1090     connect(exportLibraryDialog, SIGNAL(exportPath(QString)), this, SLOT(exportLibrary(QString)));
1091     connect(exportLibraryDialog, SIGNAL(rejected()), packageManager, SLOT(cancel()));
1092     connect(packageManager, SIGNAL(exported()), exportLibraryDialog, SLOT(close()));
1093     connect(importLibraryDialog, SIGNAL(unpackCLC(QString, QString, QString)), this, SLOT(importLibrary(QString, QString, QString)));
1094     connect(importLibraryDialog, SIGNAL(rejected()), packageManager, SLOT(cancel()));
1095     connect(importLibraryDialog, SIGNAL(rejected()), this, SLOT(deleteCurrentLibrary()));
1096     connect(importLibraryDialog, SIGNAL(libraryExists(QString)), this, SLOT(libraryAlreadyExists(QString)));
1097     connect(packageManager, SIGNAL(imported()), importLibraryDialog, SLOT(hide()));
1098     connect(packageManager, SIGNAL(imported()), this, SLOT(openLastCreated()));
1099 
1100     //create and update dialogs
1101     connect(createLibraryDialog, SIGNAL(cancelCreate()), this, SLOT(cancelCreating()));
1102 
1103     //open existing library from dialog.
1104     connect(addLibraryDialog, SIGNAL(addLibrary(QString, QString)), this, SLOT(openLibrary(QString, QString)));
1105 
1106     //load library when selected library changes
1107     connect(selectedLibrary, SIGNAL(currentIndexChanged(QString)), this, SLOT(loadLibrary(QString)));
1108 
1109     //rename library dialog
1110     connect(renameLibraryDialog, SIGNAL(renameLibrary(QString)), this, SLOT(rename(QString)));
1111 
1112     //navigations between view modes (tree,list and flow)
1113     //TODO connect(foldersView, SIGNAL(pressed(QModelIndex)), this, SLOT(updateFoldersViewConextMenu(QModelIndex)));
1114     //connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex)));
1115 
1116     //drops in folders view
1117     connect(foldersView, SIGNAL(copyComicsToFolder(QList<QPair<QString, QString>>, QModelIndex)), this, SLOT(copyAndImportComicsToFolder(QList<QPair<QString, QString>>, QModelIndex)));
1118     connect(foldersView, SIGNAL(moveComicsToFolder(QList<QPair<QString, QString>>, QModelIndex)), this, SLOT(moveAndImportComicsToFolder(QList<QPair<QString, QString>>, QModelIndex)));
1119     connect(foldersView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showFoldersContextMenu(QPoint)));
1120 
1121     //actions
1122     connect(createLibraryAction, SIGNAL(triggered()), this, SLOT(createLibrary()));
1123     connect(exportLibraryAction, SIGNAL(triggered()), exportLibraryDialog, SLOT(open()));
1124     connect(importLibraryAction, SIGNAL(triggered()), this, SLOT(importLibraryPackage()));
1125 
1126     connect(openLibraryAction, SIGNAL(triggered()), this, SLOT(showAddLibrary()));
1127     connect(setAsReadAction, SIGNAL(triggered()), this, SLOT(setCurrentComicReaded()));
1128     connect(setAsNonReadAction, SIGNAL(triggered()), this, SLOT(setCurrentComicUnreaded()));
1129     connect(setNormalAction, &QAction::triggered, this, &LibraryWindow::setSelectedComicsAsNormal);
1130     connect(setMangaAction, &QAction::triggered, this, &LibraryWindow::setSelectedComicsAsManga);
1131     //connect(setAllAsReadAction,SIGNAL(triggered()),this,SLOT(setComicsReaded()));
1132     //connect(setAllAsNonReadAction,SIGNAL(triggered()),this,SLOT(setComicsUnreaded()));
1133 
1134     //comicsInfoManagement
1135     connect(exportComicsInfoAction, SIGNAL(triggered()), this, SLOT(showExportComicsInfo()));
1136     connect(importComicsInfoAction, SIGNAL(triggered()), this, SLOT(showImportComicsInfo()));
1137 
1138     //properties & config
1139     connect(propertiesDialog, SIGNAL(accepted()), navigationController, SLOT(reselectCurrentSource()));
1140 
1141     //comic vine
1142     connect(comicVineDialog, SIGNAL(accepted()), navigationController, SLOT(reselectCurrentSource()), Qt::QueuedConnection);
1143 
1144     connect(updateLibraryAction, SIGNAL(triggered()), this, SLOT(updateLibrary()));
1145     connect(renameLibraryAction, SIGNAL(triggered()), this, SLOT(renameLibrary()));
1146     //connect(deleteLibraryAction,SIGNAL(triggered()),this,SLOT(deleteLibrary()));
1147     connect(removeLibraryAction, SIGNAL(triggered()), this, SLOT(removeLibrary()));
1148     connect(openComicAction, SIGNAL(triggered()), this, SLOT(openComic()));
1149     connect(helpAboutAction, SIGNAL(triggered()), had, SLOT(show()));
1150     connect(addFolderAction, SIGNAL(triggered()), this, SLOT(addFolderToCurrentIndex()));
1151     connect(deleteFolderAction, SIGNAL(triggered()), this, SLOT(deleteSelectedFolder()));
1152     connect(setRootIndexAction, SIGNAL(triggered()), this, SLOT(setRootIndex()));
1153     connect(expandAllNodesAction, SIGNAL(triggered()), foldersView, SLOT(expandAll()));
1154     connect(colapseAllNodesAction, SIGNAL(triggered()), foldersView, SLOT(collapseAll()));
1155 #ifndef Q_OS_MAC
1156     connect(toggleFullScreenAction, SIGNAL(triggered()), this, SLOT(toggleFullScreen()));
1157 #endif
1158     connect(toggleComicsViewAction, SIGNAL(triggered()), comicsViewsManager, SLOT(toggleComicsView()));
1159     connect(optionsAction, SIGNAL(triggered()), optionsDialog, SLOT(show()));
1160 #ifdef SERVER_RELEASE
1161     connect(serverConfigAction, SIGNAL(triggered()), serverConfigDialog, SLOT(show()));
1162 #endif
1163     connect(optionsDialog, SIGNAL(optionsChanged()), this, SLOT(reloadOptions()));
1164     connect(optionsDialog, SIGNAL(editShortcuts()), editShortcutsDialog, SLOT(show()));
1165 
1166     //Search filter
1167     connect(searchEdit, SIGNAL(filterChanged(YACReader::SearchModifiers, QString)), this, SLOT(setSearchFilter(YACReader::SearchModifiers, QString)));
1168     connect(&comicQueryResultProcessor, &ComicQueryResultProcessor::newData, this, &LibraryWindow::setComicSearchFilterData);
1169     connect(folderQueryResultProcessor.get(), &FolderQueryResultProcessor::newData, this, &LibraryWindow::setFolderSearchFilterData);
1170 
1171     //ContextMenus
1172     connect(openContainingFolderComicAction, SIGNAL(triggered()), this, SLOT(openContainingFolderComic()));
1173     connect(setFolderAsNotCompletedAction, SIGNAL(triggered()), this, SLOT(setFolderAsNotCompleted()));
1174     connect(setFolderAsCompletedAction, SIGNAL(triggered()), this, SLOT(setFolderAsCompleted()));
1175     connect(setFolderAsReadAction, SIGNAL(triggered()), this, SLOT(setFolderAsRead()));
1176     connect(setFolderAsUnreadAction, SIGNAL(triggered()), this, SLOT(setFolderAsUnread()));
1177     connect(openContainingFolderAction, SIGNAL(triggered()), this, SLOT(openContainingFolder()));
1178     connect(setFolderAsMangaAction, &QAction::triggered, this, &LibraryWindow::setFolderAsManga);
1179     connect(setFolderAsNormalAction, &QAction::triggered, this, &LibraryWindow::setFolderAsNormal);
1180 
1181     connect(resetComicRatingAction, SIGNAL(triggered()), this, SLOT(resetComicRating()));
1182 
1183     //connect(dm,SIGNAL(directoryLoaded(QString)),foldersView,SLOT(expandAll()));
1184     //connect(dm,SIGNAL(directoryLoaded(QString)),this,SLOT(updateFoldersView(QString)));
1185     //Comicts edition
1186     connect(editSelectedComicsAction, SIGNAL(triggered()), this, SLOT(showProperties()));
1187     connect(asignOrderAction, SIGNAL(triggered()), this, SLOT(asignNumbers()));
1188 
1189     connect(deleteComicsAction, SIGNAL(triggered()), this, SLOT(deleteComics()));
1190 
1191     connect(getInfoAction, SIGNAL(triggered()), this, SLOT(showComicVineScraper()));
1192 
1193     //connect(socialAction,SIGNAL(triggered()),this,SLOT(showSocial()));
1194 
1195     //connect(comicsModel,SIGNAL(isEmpty()),this,SLOT(showEmptyFolderView()));
1196     //connect(comicsModel,SIGNAL(searchNumResults(int)),this,SLOT(checkSearchNumResults(int)));
1197     //connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int)));
1198 
1199     connect(focusSearchLineAction, &QAction::triggered, searchEdit, [this] { searchEdit->setFocus(Qt::ShortcutFocusReason); });
1200     connect(focusComicsViewAction, &QAction::triggered, comicsViewsManager, &YACReaderComicsViewsManager::focusComicsViewViaShortcut);
1201 
1202     connect(showEditShortcutsAction, SIGNAL(triggered()), editShortcutsDialog, SLOT(show()));
1203 
1204     connect(quitAction, &QAction::triggered, this, &LibraryWindow::closeApp);
1205 
1206     //update folders (partial updates)
1207     connect(updateCurrentFolderAction, SIGNAL(triggered()), this, SLOT(updateCurrentFolder()));
1208     connect(updateFolderAction, SIGNAL(triggered()), this, SLOT(updateCurrentFolder()));
1209 
1210     //lists
1211     connect(addReadingListAction, SIGNAL(triggered()), this, SLOT(addNewReadingList()));
1212     connect(deleteReadingListAction, SIGNAL(triggered()), this, SLOT(deleteSelectedReadingList()));
1213     connect(addLabelAction, SIGNAL(triggered()), this, SLOT(showAddNewLabelDialog()));
1214     connect(renameListAction, SIGNAL(triggered()), this, SLOT(showRenameCurrentList()));
1215 
1216     connect(listsModel, SIGNAL(addComicsToFavorites(QList<qulonglong>)), comicsModel, SLOT(addComicsToFavorites(QList<qulonglong>)));
1217     connect(listsModel, SIGNAL(addComicsToLabel(QList<qulonglong>, qulonglong)), comicsModel, SLOT(addComicsToLabel(QList<qulonglong>, qulonglong)));
1218     connect(listsModel, SIGNAL(addComicsToReadingList(QList<qulonglong>, qulonglong)), comicsModel, SLOT(addComicsToReadingList(QList<qulonglong>, qulonglong)));
1219     //--
1220 
1221     connect(addToFavoritesAction, SIGNAL(triggered()), this, SLOT(addSelectedComicsToFavorites()));
1222 
1223     //save covers
1224     connect(saveCoversToAction, SIGNAL(triggered()), this, SLOT(saveSelectedCoversTo()));
1225 
1226     //upgrade library
1227     connect(this, SIGNAL(libraryUpgraded(QString)), this, SLOT(loadLibrary(QString)), Qt::QueuedConnection);
1228     connect(this, SIGNAL(errorUpgradingLibrary(QString)), this, SLOT(showErrorUpgradingLibrary(QString)), Qt::QueuedConnection);
1229 }
1230 
showErrorUpgradingLibrary(const QString & path)1231 void LibraryWindow::showErrorUpgradingLibrary(const QString &path)
1232 {
1233     QMessageBox::critical(this, tr("Upgrade failed"), tr("There were errors during library upgrade in: ") + path + "/library.ydb");
1234 }
1235 
loadLibrary(const QString & name)1236 void LibraryWindow::loadLibrary(const QString &name)
1237 {
1238     if (!libraries.isEmpty()) //si hay bibliotecas...
1239     {
1240         historyController->clear();
1241 
1242         showRootWidget();
1243         QString path = libraries.getPath(name) + "/.yacreaderlibrary";
1244         QDir d; //TODO change this by static methods (utils class?? with delTree for example)
1245         QString dbVersion;
1246         if (d.exists(path) && d.exists(path + "/library.ydb") && (dbVersion = DataBaseManagement::checkValidDB(path + "/library.ydb")) != "") //si existe en disco la biblioteca seleccionada, y es válida..
1247         {
1248             int comparation = DataBaseManagement::compareVersions(dbVersion, VERSION);
1249 
1250             if (comparation < 0) {
1251                 int ret = QMessageBox::question(this, tr("Update needed"), tr("This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now?"), QMessageBox::Yes, QMessageBox::No);
1252                 if (ret == QMessageBox::Yes) {
1253                     importWidget->setUpgradeLook();
1254                     showImportingWidget();
1255 
1256                     upgradeLibraryFuture = std::async(std::launch::async, [this, name, path] {
1257                         bool updated = DataBaseManagement::updateToCurrentVersion(path);
1258 
1259                         if (!updated)
1260                             emit errorUpgradingLibrary(path);
1261 
1262                         emit libraryUpgraded(name);
1263                     });
1264 
1265                     return;
1266                 } else {
1267                     comicsViewsManager->comicsView->setModel(NULL);
1268                     foldersView->setModel(NULL);
1269                     listsView->setModel(NULL);
1270                     disableAllActions(); //TODO comprobar que se deben deshabilitar
1271                     //será possible renombrar y borrar estas bibliotecas
1272                     renameLibraryAction->setEnabled(true);
1273                     removeLibraryAction->setEnabled(true);
1274                 }
1275             }
1276 
1277             if (comparation == 0) //en caso de que la versión se igual que la actual
1278             {
1279                 foldersModel->setupModelData(path);
1280                 foldersModelProxy->setSourceModel(foldersModel);
1281                 foldersView->setModel(foldersModelProxy);
1282                 foldersView->setCurrentIndex(QModelIndex()); //why is this necesary?? by default it seems that returns an arbitrary index.
1283 
1284                 listsModel->setupReadingListsData(path);
1285                 listsModelProxy->setSourceModel(listsModel);
1286                 listsView->setModel(listsModelProxy);
1287 
1288                 if (foldersModel->rowCount(QModelIndex()) > 0)
1289                     disableFoldersActions(false);
1290                 else
1291                     disableFoldersActions(true);
1292 
1293                 d.setCurrent(libraries.getPath(name));
1294                 d.setFilter(QDir::AllDirs | QDir::Files | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot);
1295                 if (d.count() <= 1) //librería de sólo lectura
1296                 {
1297                     //QMessageBox::critical(NULL,QString::number(d.count()),QString::number(d.count()));
1298                     disableLibrariesActions(false);
1299                     updateLibraryAction->setDisabled(true);
1300                     openContainingFolderAction->setDisabled(true);
1301                     disableComicsActions(true);
1302 #ifndef Q_OS_MAC
1303                     toggleFullScreenAction->setEnabled(true);
1304 #endif
1305 
1306                     importedCovers = true;
1307                 } else //librería normal abierta
1308                 {
1309                     disableLibrariesActions(false);
1310                     importedCovers = false;
1311                 }
1312 
1313                 setRootIndex();
1314 
1315                 searchEdit->clear();
1316             } else if (comparation > 0) {
1317                 int ret = QMessageBox::question(this, tr("Download new version"), tr("This library was created with a newer version of YACReaderLibrary. Download the new version now?"), QMessageBox::Yes, QMessageBox::No);
1318                 if (ret == QMessageBox::Yes)
1319                     QDesktopServices::openUrl(QUrl("http://www.yacreader.com"));
1320 
1321                 comicsViewsManager->comicsView->setModel(NULL);
1322                 foldersView->setModel(NULL);
1323                 listsView->setModel(NULL);
1324                 disableAllActions(); //TODO comprobar que se deben deshabilitar
1325                 //será possible renombrar y borrar estas bibliotecas
1326                 renameLibraryAction->setEnabled(true);
1327                 removeLibraryAction->setEnabled(true);
1328             }
1329         } else {
1330             comicsViewsManager->comicsView->setModel(NULL);
1331             foldersView->setModel(NULL);
1332             listsView->setModel(NULL);
1333             disableAllActions(); //TODO comprobar que se deben deshabilitar
1334 
1335             //si la librería no existe en disco, se ofrece al usuario la posibiliad de eliminarla
1336             if (!d.exists(path)) {
1337                 QString currentLibrary = selectedLibrary->currentText();
1338                 if (QMessageBox::question(this, tr("Library not available"), tr("Library '%1' is no longer available. Do you want to remove it?").arg(currentLibrary), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
1339                     deleteCurrentLibrary();
1340                 }
1341                 //será possible renombrar y borrar estas bibliotecas
1342                 renameLibraryAction->setEnabled(true);
1343                 removeLibraryAction->setEnabled(true);
1344 
1345             } else //si existe el path, puede ser que la librería sea alguna versión pre-5.0 ó que esté corrupta o que no haya drivers sql
1346             {
1347 
1348                 if (d.exists(path + "/library.ydb")) {
1349                     QSqlDatabase db = DataBaseManagement::loadDatabase(path);
1350                     manageOpeningLibraryError(db.lastError().databaseText() + "-" + db.lastError().driverText());
1351                     //será possible renombrar y borrar estas bibliotecas
1352                     renameLibraryAction->setEnabled(true);
1353                     removeLibraryAction->setEnabled(true);
1354                 } else {
1355                     QString currentLibrary = selectedLibrary->currentText();
1356                     QString path = libraries.getPath(selectedLibrary->currentText());
1357                     if (QMessageBox::question(this, tr("Old library"), tr("Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now?").arg(currentLibrary), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
1358                         QDir d(path + "/.yacreaderlibrary");
1359                         d.removeRecursively();
1360                         //d.rmdir(path+"/.yacreaderlibrary");
1361                         createLibraryDialog->setDataAndStart(currentLibrary, path);
1362                         //create(path,path+"/.yacreaderlibrary",currentLibrary);
1363                     }
1364                     //será possible renombrar y borrar estas bibliotecas
1365                     renameLibraryAction->setEnabled(true);
1366                     removeLibraryAction->setEnabled(true);
1367                 }
1368             }
1369         }
1370     } else //en caso de que no exista ninguna biblioteca se desactivan los botones pertinentes
1371     {
1372         disableAllActions();
1373         showNoLibrariesWidget();
1374     }
1375 }
1376 
loadCoversFromCurrentModel()1377 void LibraryWindow::loadCoversFromCurrentModel()
1378 {
1379     comicsViewsManager->comicsView->setModel(comicsModel);
1380 }
1381 
copyAndImportComicsToCurrentFolder(const QList<QPair<QString,QString>> & comics)1382 void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList<QPair<QString, QString>> &comics)
1383 {
1384     QLOG_DEBUG() << "-copyAndImportComicsToCurrentFolder-";
1385     if (comics.size() > 0) {
1386         QString destFolderPath = currentFolderPath();
1387 
1388         QModelIndex folderDestination = getCurrentFolderIndex();
1389 
1390         QProgressDialog *progressDialog = newProgressDialog(tr("Copying comics..."), comics.size());
1391 
1392         auto comicFilesManager = new ComicFilesManager();
1393         comicFilesManager->copyComicsTo(comics, destFolderPath, folderDestination);
1394 
1395         processComicFiles(comicFilesManager, progressDialog);
1396     }
1397 }
1398 
moveAndImportComicsToCurrentFolder(const QList<QPair<QString,QString>> & comics)1399 void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList<QPair<QString, QString>> &comics)
1400 {
1401     QLOG_DEBUG() << "-moveAndImportComicsToCurrentFolder-";
1402     if (comics.size() > 0) {
1403         QString destFolderPath = currentFolderPath();
1404 
1405         QModelIndex folderDestination = getCurrentFolderIndex();
1406 
1407         QProgressDialog *progressDialog = newProgressDialog(tr("Moving comics..."), comics.size());
1408 
1409         auto comicFilesManager = new ComicFilesManager();
1410         comicFilesManager->moveComicsTo(comics, destFolderPath, folderDestination);
1411 
1412         processComicFiles(comicFilesManager, progressDialog);
1413     }
1414 }
1415 
copyAndImportComicsToFolder(const QList<QPair<QString,QString>> & comics,const QModelIndex & miFolder)1416 void LibraryWindow::copyAndImportComicsToFolder(const QList<QPair<QString, QString>> &comics, const QModelIndex &miFolder)
1417 {
1418     QLOG_DEBUG() << "-copyAndImportComicsToFolder-";
1419     if (comics.size() > 0) {
1420         QModelIndex folderDestination = foldersModelProxy->mapToSource(miFolder);
1421 
1422         QString destFolderPath = QDir::cleanPath(currentPath() + foldersModel->getFolderPath(folderDestination));
1423 
1424         QLOG_DEBUG() << "Coping to " << destFolderPath;
1425 
1426         QProgressDialog *progressDialog = newProgressDialog(tr("Copying comics..."), comics.size());
1427 
1428         auto comicFilesManager = new ComicFilesManager();
1429         comicFilesManager->copyComicsTo(comics, destFolderPath, folderDestination);
1430 
1431         processComicFiles(comicFilesManager, progressDialog);
1432     }
1433 }
1434 
moveAndImportComicsToFolder(const QList<QPair<QString,QString>> & comics,const QModelIndex & miFolder)1435 void LibraryWindow::moveAndImportComicsToFolder(const QList<QPair<QString, QString>> &comics, const QModelIndex &miFolder)
1436 {
1437     QLOG_DEBUG() << "-moveAndImportComicsToFolder-";
1438     if (comics.size() > 0) {
1439         QModelIndex folderDestination = foldersModelProxy->mapToSource(miFolder);
1440 
1441         QString destFolderPath = QDir::cleanPath(currentPath() + foldersModel->getFolderPath(folderDestination));
1442 
1443         QLOG_DEBUG() << "Moving to " << destFolderPath;
1444 
1445         QProgressDialog *progressDialog = newProgressDialog(tr("Moving comics..."), comics.size());
1446 
1447         auto comicFilesManager = new ComicFilesManager();
1448         comicFilesManager->moveComicsTo(comics, destFolderPath, folderDestination);
1449 
1450         processComicFiles(comicFilesManager, progressDialog);
1451     }
1452 }
1453 
processComicFiles(ComicFilesManager * comicFilesManager,QProgressDialog * progressDialog)1454 void LibraryWindow::processComicFiles(ComicFilesManager *comicFilesManager, QProgressDialog *progressDialog)
1455 {
1456     connect(comicFilesManager, SIGNAL(progress(int)), progressDialog, SLOT(setValue(int)));
1457 
1458     QThread *thread = NULL;
1459 
1460     thread = new QThread();
1461 
1462     comicFilesManager->moveToThread(thread);
1463 
1464     connect(progressDialog, SIGNAL(canceled()), comicFilesManager, SLOT(cancel()), Qt::DirectConnection);
1465 
1466     connect(thread, SIGNAL(started()), comicFilesManager, SLOT(process()));
1467     connect(comicFilesManager, SIGNAL(success(QModelIndex)), this, SLOT(updateCopyMoveFolderDestination(QModelIndex)));
1468     connect(comicFilesManager, SIGNAL(finished()), thread, SLOT(quit()));
1469     connect(comicFilesManager, SIGNAL(finished()), comicFilesManager, SLOT(deleteLater()));
1470     connect(comicFilesManager, SIGNAL(finished()), progressDialog, SLOT(close()));
1471     connect(comicFilesManager, SIGNAL(finished()), progressDialog, SLOT(deleteLater()));
1472     connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
1473 
1474     if (thread != NULL)
1475         thread->start();
1476 }
1477 
updateCopyMoveFolderDestination(const QModelIndex & mi)1478 void LibraryWindow::updateCopyMoveFolderDestination(const QModelIndex &mi)
1479 {
1480     updateFolder(mi);
1481 }
1482 
updateCurrentFolder()1483 void LibraryWindow::updateCurrentFolder()
1484 {
1485     updateFolder(getCurrentFolderIndex());
1486 }
1487 
updateFolder(const QModelIndex & miFolder)1488 void LibraryWindow::updateFolder(const QModelIndex &miFolder)
1489 {
1490     QLOG_DEBUG() << "UPDATE FOLDER!!!!";
1491 
1492     importWidget->setUpdateLook();
1493     showImportingWidget();
1494 
1495     QString currentLibrary = selectedLibrary->currentText();
1496     QString path = libraries.getPath(currentLibrary);
1497     _lastAdded = currentLibrary;
1498     libraryCreator->updateFolder(QDir::cleanPath(path), QDir::cleanPath(path + "/.yacreaderlibrary"), QDir::cleanPath(currentPath() + foldersModel->getFolderPath(miFolder)), miFolder);
1499     libraryCreator->start();
1500 }
1501 
newProgressDialog(const QString & label,int maxValue)1502 QProgressDialog *LibraryWindow::newProgressDialog(const QString &label, int maxValue)
1503 {
1504     QProgressDialog *progressDialog = new QProgressDialog(label, "Cancel", 0, maxValue, this);
1505     progressDialog->setWindowModality(Qt::WindowModal);
1506     progressDialog->setMinimumWidth(350);
1507     progressDialog->show();
1508     return progressDialog;
1509 }
1510 
reloadAfterCopyMove(const QModelIndex & mi)1511 void LibraryWindow::reloadAfterCopyMove(const QModelIndex &mi)
1512 {
1513     if (getCurrentFolderIndex() == mi) {
1514         navigationController->loadFolderInfo(mi);
1515     }
1516 
1517     foldersModel->fetchMoreFromDB(mi);
1518 
1519     enableNeededActions();
1520 }
1521 
getCurrentFolderIndex()1522 QModelIndex LibraryWindow::getCurrentFolderIndex()
1523 {
1524     if (foldersView->selectionModel()->selectedRows().length() > 0)
1525         return foldersModelProxy->mapToSource(foldersView->currentIndex());
1526     else
1527         return QModelIndex();
1528 }
1529 
enableNeededActions()1530 void LibraryWindow::enableNeededActions()
1531 {
1532     if (foldersModel->rowCount(QModelIndex()) > 0)
1533         disableFoldersActions(false);
1534 
1535     if (comicsModel->rowCount() > 0)
1536         disableComicsActions(false);
1537 
1538     disableLibrariesActions(false);
1539 }
1540 
addFolderToCurrentIndex()1541 void LibraryWindow::addFolderToCurrentIndex()
1542 {
1543     QModelIndex currentIndex = getCurrentFolderIndex();
1544 
1545     bool ok;
1546     QString newFolderName = QInputDialog::getText(this, tr("Add new folder"),
1547                                                   tr("Folder name:"), QLineEdit::Normal,
1548                                                   "", &ok);
1549 
1550     //chars not supported in a folder's name: / \ : * ? " < > |
1551     QRegExp invalidChars("\\/\\:\\*\\?\\\"\\<\\>\\|\\\\"); //TODO this regexp is not properly written
1552     bool isValid = !newFolderName.contains(invalidChars);
1553 
1554     if (ok && !newFolderName.isEmpty() && isValid) {
1555         QString parentPath = QDir::cleanPath(currentPath() + foldersModel->getFolderPath(currentIndex));
1556         QDir parentDir(parentPath);
1557         QDir newFolder(parentPath + "/" + newFolderName);
1558         if (parentDir.mkdir(newFolderName) || newFolder.exists()) {
1559             QModelIndex newIndex = foldersModel->addFolderAtParent(newFolderName, currentIndex);
1560             foldersView->setCurrentIndex(foldersModelProxy->mapFromSource(newIndex));
1561             navigationController->loadFolderInfo(newIndex);
1562             historyController->updateHistory(YACReaderLibrarySourceContainer(newIndex, YACReaderLibrarySourceContainer::Folder));
1563             //a new folder is always an empty folder
1564             comicsViewsManager->showEmptyFolderView();
1565         }
1566     }
1567 }
1568 
deleteSelectedFolder()1569 void LibraryWindow::deleteSelectedFolder()
1570 {
1571     QModelIndex currentIndex = getCurrentFolderIndex();
1572     QString relativePath = foldersModel->getFolderPath(currentIndex);
1573     QString folderPath = QDir::cleanPath(currentPath() + relativePath);
1574 
1575     if (!currentIndex.isValid())
1576         QMessageBox::information(this, tr("No folder selected"), tr("Please, select a folder first"));
1577     else {
1578         QString libraryPath = QDir::cleanPath(currentPath());
1579         if ((libraryPath == folderPath) || relativePath.isEmpty() || relativePath == "/")
1580             QMessageBox::critical(this, tr("Error in path"), tr("There was an error accessing the folder's path"));
1581         else {
1582             int ret = QMessageBox::question(this, tr("Delete folder"), tr("The selected folder and all its contents will be deleted from your disk. Are you sure?") + "\n\nFolder : " + folderPath, QMessageBox::Yes, QMessageBox::No);
1583 
1584             if (ret == QMessageBox::Yes) {
1585                 //no folders multiselection by now
1586                 QModelIndexList indexList;
1587                 indexList << currentIndex;
1588 
1589                 QList<QString> paths;
1590                 paths << folderPath;
1591 
1592                 auto remover = new FoldersRemover(indexList, paths);
1593                 const auto thread = new QThread(this);
1594                 moveAndConnectRemoverToThread(remover, thread);
1595 
1596                 connect(remover, SIGNAL(remove(QModelIndex)), foldersModel, SLOT(deleteFolder(QModelIndex)));
1597                 connect(remover, SIGNAL(removeError()), this, SLOT(errorDeletingFolder()));
1598                 connect(remover, SIGNAL(finished()), navigationController, SLOT(reselectCurrentFolder()));
1599 
1600                 thread->start();
1601             }
1602         }
1603     }
1604 }
1605 
errorDeletingFolder()1606 void LibraryWindow::errorDeletingFolder()
1607 {
1608     QMessageBox::critical(this, tr("Unable to delete"), tr("There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files."));
1609 }
1610 
addNewReadingList()1611 void LibraryWindow::addNewReadingList()
1612 {
1613     QModelIndexList selectedLists = listsView->selectionModel()->selectedIndexes();
1614     QModelIndex sourceMI;
1615     if (!selectedLists.isEmpty())
1616         sourceMI = listsModelProxy->mapToSource(selectedLists.at(0));
1617 
1618     if (selectedLists.isEmpty() || !listsModel->isReadingSubList(sourceMI)) {
1619         bool ok;
1620         QString newListName = QInputDialog::getText(this, tr("Add new reading lists"),
1621                                                     tr("List name:"), QLineEdit::Normal,
1622                                                     "", &ok);
1623         if (ok) {
1624             if (selectedLists.isEmpty() || !listsModel->isReadingList(sourceMI))
1625                 listsModel->addReadingList(newListName); //top level
1626             else {
1627                 listsModel->addReadingListAt(newListName, sourceMI); //sublist
1628             }
1629         }
1630     }
1631 }
1632 
deleteSelectedReadingList()1633 void LibraryWindow::deleteSelectedReadingList()
1634 {
1635     QModelIndexList selectedLists = listsView->selectionModel()->selectedIndexes();
1636     if (!selectedLists.isEmpty()) {
1637         QModelIndex mi = listsModelProxy->mapToSource(selectedLists.at(0));
1638         if (listsModel->isEditable(mi)) {
1639             int ret = QMessageBox::question(this, tr("Delete list/label"), tr("The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure?"), QMessageBox::Yes, QMessageBox::No);
1640             if (ret == QMessageBox::Yes) {
1641                 listsModel->deleteItem(mi);
1642                 navigationController->reselectCurrentList();
1643             }
1644         }
1645     }
1646 }
1647 
showAddNewLabelDialog()1648 void LibraryWindow::showAddNewLabelDialog()
1649 {
1650     auto dialog = new AddLabelDialog();
1651     int ret = dialog->exec();
1652 
1653     if (ret == QDialog::Accepted) {
1654         YACReader::LabelColors color = dialog->selectedColor();
1655         QString name = dialog->name();
1656 
1657         listsModel->addNewLabel(name, color);
1658     }
1659 }
1660 
1661 //TODO implement editors in treeview
showRenameCurrentList()1662 void LibraryWindow::showRenameCurrentList()
1663 {
1664     QModelIndexList selectedLists = listsView->selectionModel()->selectedIndexes();
1665     if (!selectedLists.isEmpty()) {
1666         QModelIndex mi = listsModelProxy->mapToSource(selectedLists.at(0));
1667         if (listsModel->isEditable(mi)) {
1668             bool ok;
1669             QString newListName = QInputDialog::getText(this, tr("Rename list name"),
1670                                                         tr("List name:"), QLineEdit::Normal,
1671                                                         listsModel->name(mi), &ok);
1672 
1673             if (ok)
1674                 listsModel->rename(mi, newListName);
1675         }
1676     }
1677 }
1678 
addSelectedComicsToFavorites()1679 void LibraryWindow::addSelectedComicsToFavorites()
1680 {
1681     QModelIndexList indexList = getSelectedComics();
1682     comicsModel->addComicsToFavorites(indexList);
1683 }
1684 
showComicsViewContextMenu(const QPoint & point)1685 void LibraryWindow::showComicsViewContextMenu(const QPoint &point)
1686 {
1687     QMenu menu;
1688 
1689     menu.addAction(openComicAction);
1690     menu.addAction(saveCoversToAction);
1691     menu.addSeparator();
1692     menu.addAction(openContainingFolderComicAction);
1693     menu.addAction(updateCurrentFolderAction);
1694     menu.addSeparator();
1695     menu.addAction(resetComicRatingAction);
1696     menu.addSeparator();
1697     menu.addAction(editSelectedComicsAction);
1698     menu.addAction(getInfoAction);
1699     menu.addAction(asignOrderAction);
1700     menu.addSeparator();
1701     menu.addAction(selectAllComicsAction);
1702     menu.addSeparator();
1703     menu.addAction(setAsReadAction);
1704     menu.addAction(setAsNonReadAction);
1705     menu.addSeparator();
1706     menu.addAction(setNormalAction);
1707     menu.addAction(setMangaAction);
1708     menu.addSeparator();
1709     menu.addAction(deleteComicsAction);
1710     menu.addSeparator();
1711     menu.addAction(addToMenuAction);
1712     QMenu subMenu;
1713     setupAddToSubmenu(subMenu);
1714 
1715 #ifndef Q_OS_MAC
1716     menu.addSeparator();
1717     menu.addAction(toggleFullScreenAction);
1718 #endif
1719 
1720     menu.exec(comicsViewsManager->comicsView->mapToGlobal(point));
1721 }
1722 
showComicsItemContextMenu(const QPoint & point)1723 void LibraryWindow::showComicsItemContextMenu(const QPoint &point)
1724 {
1725     QMenu menu;
1726 
1727     menu.addAction(openComicAction);
1728     menu.addAction(saveCoversToAction);
1729     menu.addSeparator();
1730     menu.addAction(openContainingFolderComicAction);
1731     menu.addAction(updateCurrentFolderAction);
1732     menu.addSeparator();
1733     menu.addAction(resetComicRatingAction);
1734     menu.addSeparator();
1735     menu.addAction(editSelectedComicsAction);
1736     menu.addAction(getInfoAction);
1737     menu.addAction(asignOrderAction);
1738     menu.addSeparator();
1739     menu.addAction(setAsReadAction);
1740     menu.addAction(setAsNonReadAction);
1741     menu.addSeparator();
1742     menu.addAction(setNormalAction);
1743     menu.addAction(setMangaAction);
1744     menu.addSeparator();
1745     menu.addAction(deleteComicsAction);
1746     menu.addSeparator();
1747     menu.addAction(addToMenuAction);
1748     QMenu subMenu;
1749     setupAddToSubmenu(subMenu);
1750 
1751     menu.exec(comicsViewsManager->comicsView->mapToGlobal(point));
1752 }
1753 
setupAddToSubmenu(QMenu & menu)1754 void LibraryWindow::setupAddToSubmenu(QMenu &menu)
1755 {
1756     menu.addAction(addToFavoritesAction);
1757     addToMenuAction->setMenu(&menu);
1758 
1759     const QList<LabelItem *> labels = listsModel->getLabels();
1760     if (labels.count() > 0)
1761         menu.addSeparator();
1762     foreach (LabelItem *label, labels) {
1763         auto action = new QAction(this);
1764         action->setIcon(label->getIcon());
1765         action->setText(label->name());
1766 
1767         action->setData(label->getId());
1768 
1769         menu.addAction(action);
1770 
1771         connect(action, SIGNAL(triggered()), this, SLOT(onAddComicsToLabel()));
1772     }
1773 }
1774 
onAddComicsToLabel()1775 void LibraryWindow::onAddComicsToLabel()
1776 {
1777     auto action = static_cast<QAction *>(sender());
1778 
1779     qulonglong labelId = action->data().toULongLong();
1780 
1781     QModelIndexList comics = getSelectedComics();
1782 
1783     comicsModel->addComicsToLabel(comics, labelId);
1784 }
1785 
setToolbarTitle(const QModelIndex & modelIndex)1786 void LibraryWindow::setToolbarTitle(const QModelIndex &modelIndex)
1787 {
1788 #ifndef Q_OS_MAC
1789     if (!modelIndex.isValid())
1790         libraryToolBar->setCurrentFolderName(selectedLibrary->currentText());
1791     else
1792         libraryToolBar->setCurrentFolderName(modelIndex.data().toString());
1793 #endif
1794 }
1795 
saveSelectedCoversTo()1796 void LibraryWindow::saveSelectedCoversTo()
1797 {
1798     QFileDialog saveDialog;
1799     QString folderPath = saveDialog.getExistingDirectory(this, tr("Save covers"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
1800     if (!folderPath.isEmpty()) {
1801         QModelIndexList comics = getSelectedComics();
1802         foreach (QModelIndex comic, comics) {
1803             QString origin = comic.data(ComicModel::CoverPathRole).toString().remove("file:///");
1804             QString destination = QDir(folderPath).filePath(comic.data(ComicModel::FileNameRole).toString() + ".jpg");
1805 
1806             QLOG_DEBUG() << "From : " << origin;
1807             QLOG_DEBUG() << "To : " << destination;
1808 
1809             QFile::copy(origin, destination);
1810         }
1811     }
1812 }
1813 
checkMaxNumLibraries()1814 void LibraryWindow::checkMaxNumLibraries()
1815 {
1816     int numLibraries = libraries.getNames().length();
1817     if (numLibraries >= MAX_LIBRARIES_WARNING_NUM) {
1818         QMessageBox::warning(this, tr("You are adding too many libraries."), tr("You are adding too many libraries.\n\nYou probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar.\n\nYACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low."));
1819     }
1820 }
1821 
selectSubfolder(const QModelIndex & mi,int child)1822 void LibraryWindow::selectSubfolder(const QModelIndex &mi, int child)
1823 {
1824     QModelIndex dest = foldersModel->index(child, 0, mi);
1825     foldersView->setCurrentIndex(dest);
1826     navigationController->selectedFolder(dest);
1827 }
1828 
1829 //this methods is only using after deleting comics
1830 //TODO broken window :)
checkEmptyFolder()1831 void LibraryWindow::checkEmptyFolder()
1832 {
1833     if (comicsModel->rowCount() > 0 && !importedCovers) {
1834         disableComicsActions(false);
1835     } else {
1836         disableComicsActions(true);
1837 #ifndef Q_OS_MAC
1838         if (comicsModel->rowCount() > 0)
1839             toggleFullScreenAction->setEnabled(true);
1840 #endif
1841         if (comicsModel->rowCount() == 0)
1842             navigationController->reselectCurrentFolder();
1843     }
1844 }
1845 
openComic()1846 void LibraryWindow::openComic()
1847 {
1848     if (!importedCovers) {
1849 
1850         auto comic = comicsModel->getComic(comicsViewsManager->comicsView->currentIndex());
1851         auto mode = comicsModel->getMode();
1852 
1853         openComic(comic, mode);
1854     }
1855 }
1856 
openComic(const ComicDB & comic,const ComicModel::Mode mode)1857 void LibraryWindow::openComic(const ComicDB &comic, const ComicModel::Mode mode)
1858 {
1859     auto libraryId = libraries.getId(selectedLibrary->currentText());
1860 
1861     OpenComicSource::Source source;
1862 
1863     if (mode == ComicModel::ReadingList) {
1864         source = OpenComicSource::Source::ReadingList;
1865     } else if (mode == ComicModel::Reading) {
1866         //TODO check where the comic was opened from the last time it was read
1867         source = OpenComicSource::Source::Folder;
1868     } else {
1869         source = OpenComicSource::Source::Folder;
1870     }
1871 
1872     auto yacreaderFound = YACReader::openComic(comic, libraryId, currentPath(), OpenComicSource { source, comicsModel->getSourceId() });
1873 
1874     if (!yacreaderFound) {
1875 #ifdef Q_OS_WIN
1876         QMessageBox::critical(this, tr("YACReader not found"), tr("YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary."));
1877 #else
1878         QMessageBox::critical(this, tr("YACReader not found"), tr("YACReader not found. There might be a problem with your YACReader installation."));
1879 #endif
1880     }
1881 }
1882 
setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus)1883 void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus)
1884 {
1885     comicsModel->setComicsRead(getSelectedComics(), readStatus);
1886     comicsViewsManager->updateCurrentComicView();
1887 }
1888 
setCurrentComicReaded()1889 void LibraryWindow::setCurrentComicReaded()
1890 {
1891     this->setCurrentComicsStatusReaded(YACReader::Read);
1892 }
1893 
setCurrentComicUnreaded()1894 void LibraryWindow::setCurrentComicUnreaded()
1895 {
1896     this->setCurrentComicsStatusReaded(YACReader::Unread);
1897 }
1898 
setSelectedComicsAsNormal()1899 void LibraryWindow::setSelectedComicsAsNormal()
1900 {
1901     comicsModel->setComicsManga(getSelectedComics(), false);
1902 }
1903 
setSelectedComicsAsManga()1904 void LibraryWindow::setSelectedComicsAsManga()
1905 {
1906     comicsModel->setComicsManga(getSelectedComics(), true);
1907 }
1908 
createLibrary()1909 void LibraryWindow::createLibrary()
1910 {
1911     checkMaxNumLibraries();
1912     createLibraryDialog->open(libraries);
1913 }
1914 
create(QString source,QString dest,QString name)1915 void LibraryWindow::create(QString source, QString dest, QString name)
1916 {
1917     QLOG_INFO() << QString("About to create a library from '%1' to '%2' with name '%3'").arg(source).arg(dest).arg(name);
1918     libraryCreator->createLibrary(source, dest);
1919     libraryCreator->start();
1920     _lastAdded = name;
1921     _sourceLastAdded = source;
1922 
1923     importWidget->setImportLook();
1924     showImportingWidget();
1925 }
1926 
reloadCurrentLibrary()1927 void LibraryWindow::reloadCurrentLibrary()
1928 {
1929     loadLibrary(selectedLibrary->currentText());
1930 }
1931 
openLastCreated()1932 void LibraryWindow::openLastCreated()
1933 {
1934 
1935     selectedLibrary->disconnect();
1936 
1937     selectedLibrary->setCurrentIndex(selectedLibrary->findText(_lastAdded));
1938     libraries.addLibrary(_lastAdded, _sourceLastAdded);
1939     selectedLibrary->addItem(_lastAdded, _sourceLastAdded);
1940     selectedLibrary->setCurrentIndex(selectedLibrary->findText(_lastAdded));
1941     libraries.save();
1942 
1943     connect(selectedLibrary, SIGNAL(currentIndexChanged(QString)), this, SLOT(loadLibrary(QString)));
1944 
1945     loadLibrary(_lastAdded);
1946 }
1947 
showAddLibrary()1948 void LibraryWindow::showAddLibrary()
1949 {
1950     checkMaxNumLibraries();
1951     addLibraryDialog->open();
1952 }
1953 
openLibrary(QString path,QString name)1954 void LibraryWindow::openLibrary(QString path, QString name)
1955 {
1956     if (!libraries.contains(name)) {
1957         //TODO: fix bug, /a/b/c/.yacreaderlibrary/d/e
1958         path.remove("/.yacreaderlibrary");
1959         QDir d; //TODO change this by static methods (utils class?? with delTree for example)
1960         if (d.exists(path + "/.yacreaderlibrary")) {
1961             _lastAdded = name;
1962             _sourceLastAdded = path;
1963             openLastCreated();
1964             addLibraryDialog->close();
1965         } else
1966             QMessageBox::warning(this, tr("Library not found"), tr("The selected folder doesn't contain any library."));
1967     } else {
1968         libraryAlreadyExists(name);
1969     }
1970 }
1971 
loadLibraries()1972 void LibraryWindow::loadLibraries()
1973 {
1974     libraries.load();
1975     foreach (QString name, libraries.getNames())
1976         selectedLibrary->addItem(name, libraries.getPath(name));
1977 }
1978 
saveLibraries()1979 void LibraryWindow::saveLibraries()
1980 {
1981     libraries.save();
1982 }
1983 
updateLibrary()1984 void LibraryWindow::updateLibrary()
1985 {
1986     importWidget->setUpdateLook();
1987     showImportingWidget();
1988 
1989     QString currentLibrary = selectedLibrary->currentText();
1990     QString path = libraries.getPath(currentLibrary);
1991     _lastAdded = currentLibrary;
1992     libraryCreator->updateLibrary(path, path + "/.yacreaderlibrary");
1993     libraryCreator->start();
1994 }
1995 
deleteCurrentLibrary()1996 void LibraryWindow::deleteCurrentLibrary()
1997 {
1998     QString path = libraries.getPath(selectedLibrary->currentText());
1999     libraries.remove(selectedLibrary->currentText());
2000     selectedLibrary->removeItem(selectedLibrary->currentIndex());
2001     //selectedLibrary->setCurrentIndex(0);
2002     path = path + "/.yacreaderlibrary";
2003 
2004     QDir d(path);
2005     d.removeRecursively();
2006     if (libraries.isEmpty()) //no more libraries available.
2007     {
2008         comicsViewsManager->comicsView->setModel(NULL);
2009         foldersView->setModel(NULL);
2010         listsView->setModel(NULL);
2011 
2012         disableAllActions();
2013         showNoLibrariesWidget();
2014     }
2015     libraries.save();
2016 }
2017 
removeLibrary()2018 void LibraryWindow::removeLibrary()
2019 {
2020     QString currentLibrary = selectedLibrary->currentText();
2021     QMessageBox *messageBox = new QMessageBox(tr("Are you sure?"), tr("Do you want remove ") + currentLibrary + tr(" library?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::YesToAll, QMessageBox::No);
2022     messageBox->button(QMessageBox::YesToAll)->setText(tr("Remove and delete metadata"));
2023     messageBox->setParent(this);
2024     messageBox->setWindowModality(Qt::WindowModal);
2025     int ret = messageBox->exec();
2026     if (ret == QMessageBox::Yes) {
2027         libraries.remove(currentLibrary);
2028         selectedLibrary->removeItem(selectedLibrary->currentIndex());
2029         //selectedLibrary->setCurrentIndex(0);
2030         if (libraries.isEmpty()) //no more libraries available.
2031         {
2032             comicsViewsManager->comicsView->setModel(NULL);
2033             foldersView->setModel(NULL);
2034             listsView->setModel(NULL);
2035 
2036             disableAllActions();
2037             showNoLibrariesWidget();
2038         }
2039         libraries.save();
2040     } else if (ret == QMessageBox::YesToAll) {
2041         deleteCurrentLibrary();
2042     }
2043 }
2044 
renameLibrary()2045 void LibraryWindow::renameLibrary()
2046 {
2047     renameLibraryDialog->open();
2048 }
2049 
rename(QString newName)2050 void LibraryWindow::rename(QString newName) //TODO replace
2051 {
2052     QString currentLibrary = selectedLibrary->currentText();
2053     if (newName != currentLibrary) {
2054         if (!libraries.contains(newName)) {
2055             libraries.rename(currentLibrary, newName);
2056             //selectedLibrary->removeItem(selectedLibrary->currentIndex());
2057             //libraries.addLibrary(newName,path);
2058             selectedLibrary->renameCurrentLibrary(newName);
2059             libraries.save();
2060             renameLibraryDialog->close();
2061 #ifndef Q_OS_MAC
2062             if (!foldersModelProxy->mapToSource(foldersView->currentIndex()).isValid())
2063                 libraryToolBar->setCurrentFolderName(selectedLibrary->currentText());
2064 #endif
2065         } else {
2066             libraryAlreadyExists(newName);
2067         }
2068     } else
2069         renameLibraryDialog->close();
2070     //selectedLibrary->setCurrentIndex(selectedLibrary->findText(newName));
2071 }
2072 
cancelCreating()2073 void LibraryWindow::cancelCreating()
2074 {
2075     stopLibraryCreator();
2076 }
2077 
stopLibraryCreator()2078 void LibraryWindow::stopLibraryCreator()
2079 {
2080     libraryCreator->stop();
2081     libraryCreator->wait();
2082 }
2083 
setRootIndex()2084 void LibraryWindow::setRootIndex()
2085 {
2086     if (!libraries.isEmpty()) {
2087         QString path = libraries.getPath(selectedLibrary->currentText()) + "/.yacreaderlibrary";
2088         QDir d; //TODO change this by static methods (utils class?? with delTree for example)
2089         if (d.exists(path)) {
2090             navigationController->selectedFolder(QModelIndex());
2091         } else {
2092             comicsViewsManager->comicsView->setModel(NULL);
2093         }
2094 
2095         foldersView->selectionModel()->clear();
2096     }
2097 }
2098 
toggleFullScreen()2099 void LibraryWindow::toggleFullScreen()
2100 {
2101     fullscreen ? toNormal() : toFullScreen();
2102     fullscreen = !fullscreen;
2103 }
2104 
2105 #ifdef Q_OS_WIN //fullscreen mode in Windows for preventing this bug: QTBUG-41309 https://bugreports.qt.io/browse/QTBUG-41309
toFullScreen()2106 void LibraryWindow::toFullScreen()
2107 {
2108     fromMaximized = this->isMaximized();
2109 
2110     sideBar->hide();
2111     libraryToolBar->hide();
2112 
2113     previousWindowFlags = windowFlags();
2114     previousPos = pos();
2115     previousSize = size();
2116 
2117     showNormal();
2118     setWindowFlags(previousWindowFlags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
2119 
2120     QRect r = windowHandle()->screen()->geometry();
2121 
2122     r.setHeight(r.height() + 1);
2123 
2124     setGeometry(r);
2125     show();
2126 
2127     comicsViewsManager->comicsView->toFullScreen();
2128 }
2129 
toNormal()2130 void LibraryWindow::toNormal()
2131 {
2132     sideBar->show();
2133     libraryToolBar->show();
2134 
2135     setWindowFlags(previousWindowFlags);
2136     move(previousPos);
2137     resize(previousSize);
2138     show();
2139 
2140     if (fromMaximized)
2141         showMaximized();
2142 
2143     comicsViewsManager->comicsView->toNormal();
2144 }
2145 
2146 #else
2147 
toFullScreen()2148 void LibraryWindow::toFullScreen()
2149 {
2150     fromMaximized = this->isMaximized();
2151 
2152     sideBar->hide();
2153     libraryToolBar->hide();
2154 
2155     comicsViewsManager->comicsView->toFullScreen();
2156 
2157     showFullScreen();
2158 }
2159 
toNormal()2160 void LibraryWindow::toNormal()
2161 {
2162     sideBar->show();
2163 
2164     comicsViewsManager->comicsView->toNormal();
2165 
2166     if (fromMaximized)
2167         showMaximized();
2168     else
2169         showNormal();
2170 
2171 #ifdef Q_OS_MAC
2172     auto timer = new QTimer();
2173     timer->setSingleShot(true);
2174     timer->start();
2175     connect(timer, SIGNAL(timeout()), libraryToolBar, SLOT(show()));
2176     connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()));
2177 #else
2178     libraryToolBar->show();
2179 #endif
2180 }
2181 
2182 #endif
2183 
setSearchFilter(const YACReader::SearchModifiers modifier,QString filter)2184 void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, QString filter)
2185 {
2186     if (!filter.isEmpty()) {
2187         folderQueryResultProcessor->createModelData(modifier, filter, true);
2188         comicQueryResultProcessor.createModelData(modifier, filter, foldersModel->getDatabase());
2189     } else if (status == LibraryWindow::Searching) { //if no searching, then ignore this
2190         clearSearchFilter();
2191         navigationController->loadPreviousStatus();
2192     }
2193 }
2194 
setComicSearchFilterData(QList<ComicItem * > * data,const QString & databasePath)2195 void LibraryWindow::setComicSearchFilterData(QList<ComicItem *> *data, const QString &databasePath)
2196 {
2197     status = LibraryWindow::Searching;
2198 
2199     comicsModel->setModelData(data, databasePath);
2200     comicsViewsManager->comicsView->enableFilterMode(true);
2201     comicsViewsManager->comicsView->setModel(comicsModel); //TODO, columns are messed up after ResetModel some times, this shouldn't be necesary
2202 
2203     if (comicsModel->rowCount() == 0) {
2204         comicsViewsManager->showNoSearchResultsView();
2205         disableComicsActions(true);
2206     } else {
2207         comicsViewsManager->showComicsView();
2208         disableComicsActions(false);
2209     }
2210 }
2211 
setFolderSearchFilterData(QMap<unsigned long long,FolderItem * > * filteredItems,FolderItem * root)2212 void LibraryWindow::setFolderSearchFilterData(QMap<unsigned long long, FolderItem *> *filteredItems, FolderItem *root)
2213 {
2214     foldersModelProxy->setFilterData(filteredItems, root);
2215     foldersView->expandAll();
2216 }
2217 
clearSearchFilter()2218 void LibraryWindow::clearSearchFilter()
2219 {
2220     foldersModelProxy->clear();
2221     comicsViewsManager->comicsView->enableFilterMode(false);
2222     foldersView->collapseAll();
2223     status = LibraryWindow::Normal;
2224 }
2225 
showProperties()2226 void LibraryWindow::showProperties()
2227 {
2228     QModelIndexList indexList = getSelectedComics();
2229 
2230     QList<ComicDB> comics = comicsModel->getComics(indexList);
2231     ComicDB c = comics[0];
2232     _comicIdEdited = c.id; //static_cast<TableItem*>(indexList[0].internalPointer())->data(4).toULongLong();
2233 
2234     propertiesDialog->databasePath = foldersModel->getDatabase();
2235     propertiesDialog->basePath = currentPath();
2236     propertiesDialog->setComics(comics);
2237 
2238     propertiesDialog->show();
2239 }
2240 
showComicVineScraper()2241 void LibraryWindow::showComicVineScraper()
2242 {
2243     QSettings s(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor
2244     s.beginGroup("ComicVine");
2245 
2246     if (!s.contains(COMIC_VINE_API_KEY)) {
2247         ApiKeyDialog d;
2248         d.exec();
2249     }
2250 
2251     //check if the api key was inserted
2252     if (s.contains(COMIC_VINE_API_KEY)) {
2253         QModelIndexList indexList = getSelectedComics();
2254 
2255         QList<ComicDB> comics = comicsModel->getComics(indexList);
2256         ComicDB c = comics[0];
2257         _comicIdEdited = c.id; //static_cast<TableItem*>(indexList[0].internalPointer())->data(4).toULongLong();
2258 
2259         comicVineDialog->databasePath = foldersModel->getDatabase();
2260         comicVineDialog->basePath = currentPath();
2261         comicVineDialog->setComics(comics);
2262 
2263         comicVineDialog->show();
2264     }
2265 }
2266 
setRemoveError()2267 void LibraryWindow::setRemoveError()
2268 {
2269     removeError = true;
2270 }
2271 
checkRemoveError()2272 void LibraryWindow::checkRemoveError()
2273 {
2274     if (removeError) {
2275         QMessageBox::critical(this, tr("Unable to delete"), tr("There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder."));
2276     }
2277     removeError = false;
2278 }
2279 
resetComicRating()2280 void LibraryWindow::resetComicRating()
2281 {
2282     QModelIndexList indexList = getSelectedComics();
2283 
2284     comicsModel->startTransaction();
2285     for (auto &index : indexList) {
2286         comicsModel->resetComicRating(index);
2287     }
2288     comicsModel->finishTransaction();
2289 }
2290 
checkSearchNumResults(int numResults)2291 void LibraryWindow::checkSearchNumResults(int numResults)
2292 {
2293     if (numResults == 0)
2294         comicsViewsManager->showNoSearchResultsView();
2295     else
2296         comicsViewsManager->showComicsView();
2297 }
2298 
asignNumbers()2299 void LibraryWindow::asignNumbers()
2300 {
2301     QModelIndexList indexList = getSelectedComics();
2302 
2303     int startingNumber = indexList[0].row() + 1;
2304     if (indexList.count() > 1) {
2305         bool ok;
2306         int n = QInputDialog::getInt(this, tr("Assign comics numbers"),
2307                                      tr("Assign numbers starting in:"), startingNumber, 0, 2147483647, 1, &ok);
2308         if (ok)
2309             startingNumber = n;
2310         else
2311             return;
2312     }
2313     qint64 edited = comicsModel->asignNumbers(indexList, startingNumber);
2314 
2315     //TODO add resorting without reloading
2316     navigationController->loadFolderInfo(foldersModelProxy->mapToSource(foldersView->currentIndex()));
2317 
2318     const QModelIndex &mi = comicsModel->getIndexFromId(edited);
2319     if (mi.isValid()) {
2320         comicsViewsManager->comicsView->scrollTo(mi, QAbstractItemView::PositionAtCenter);
2321         comicsViewsManager->comicsView->setCurrentIndex(mi);
2322     }
2323 }
2324 
openContainingFolderComic()2325 void LibraryWindow::openContainingFolderComic()
2326 {
2327     QModelIndex modelIndex = comicsViewsManager->comicsView->currentIndex();
2328     QFileInfo file = QDir::cleanPath(currentPath() + comicsModel->getComicPath(modelIndex));
2329 #if defined Q_OS_UNIX && !defined Q_OS_MAC
2330     QString path = file.absolutePath();
2331     QDesktopServices::openUrl(QUrl("file:///" + path, QUrl::TolerantMode));
2332 #endif
2333 
2334 #ifdef Q_OS_MAC
2335     QString filePath = file.absoluteFilePath();
2336     QStringList args;
2337     args << "-e";
2338     args << "tell application \"Finder\"";
2339     args << "-e";
2340     args << "activate";
2341     args << "-e";
2342     args << "select POSIX file \"" + filePath + "\"";
2343     args << "-e";
2344     args << "end tell";
2345     QProcess::startDetached("osascript", args);
2346 #endif
2347 
2348 #ifdef Q_OS_WIN
2349     QString filePath = file.absoluteFilePath();
2350     QString cmdArgs = QString("/select,\"") + QDir::toNativeSeparators(filePath) + QStringLiteral("\"");
2351     ShellExecuteW(0, L"open", L"explorer.exe", reinterpret_cast<LPCWSTR>(cmdArgs.utf16()), 0, SW_NORMAL);
2352 #endif
2353 }
2354 
openContainingFolder()2355 void LibraryWindow::openContainingFolder()
2356 {
2357     QModelIndex modelIndex = foldersModelProxy->mapToSource(foldersView->currentIndex());
2358     QString path;
2359     if (modelIndex.isValid())
2360         path = QDir::cleanPath(currentPath() + foldersModel->getFolderPath(modelIndex));
2361     else
2362         path = QDir::cleanPath(currentPath());
2363     QDesktopServices::openUrl(QUrl("file:///" + path, QUrl::TolerantMode));
2364 }
2365 
setFolderAsNotCompleted()2366 void LibraryWindow::setFolderAsNotCompleted()
2367 {
2368     //foldersModel->updateFolderCompletedStatus(foldersView->selectionModel()->selectedRows(),false);
2369     foldersModel->updateFolderCompletedStatus(QModelIndexList() << foldersModelProxy->mapToSource(foldersView->currentIndex()), false);
2370 }
2371 
setFolderAsCompleted()2372 void LibraryWindow::setFolderAsCompleted()
2373 {
2374     //foldersModel->updateFolderCompletedStatus(foldersView->selectionModel()->selectedRows(),true);
2375     foldersModel->updateFolderCompletedStatus(QModelIndexList() << foldersModelProxy->mapToSource(foldersView->currentIndex()), true);
2376 }
2377 
setFolderAsRead()2378 void LibraryWindow::setFolderAsRead()
2379 {
2380     //foldersModel->updateFolderFinishedStatus(foldersView->selectionModel()->selectedRows(),true);
2381     foldersModel->updateFolderFinishedStatus(QModelIndexList() << foldersModelProxy->mapToSource(foldersView->currentIndex()), true);
2382 }
2383 
setFolderAsUnread()2384 void LibraryWindow::setFolderAsUnread()
2385 {
2386     //foldersModel->updateFolderFinishedStatus(foldersView->selectionModel()->selectedRows(),false);
2387     foldersModel->updateFolderFinishedStatus(QModelIndexList() << foldersModelProxy->mapToSource(foldersView->currentIndex()), false);
2388 }
2389 
setFolderAsManga()2390 void LibraryWindow::setFolderAsManga()
2391 {
2392     foldersModel->updateFolderManga(QModelIndexList() << foldersModelProxy->mapToSource(foldersView->currentIndex()), true);
2393 }
2394 
setFolderAsNormal()2395 void LibraryWindow::setFolderAsNormal()
2396 {
2397     foldersModel->updateFolderManga(QModelIndexList() << foldersModelProxy->mapToSource(foldersView->currentIndex()), false);
2398 }
2399 
exportLibrary(QString destPath)2400 void LibraryWindow::exportLibrary(QString destPath)
2401 {
2402     QString currentLibrary = selectedLibrary->currentText();
2403     QString path = libraries.getPath(currentLibrary) + "/.yacreaderlibrary";
2404     packageManager->createPackage(path, destPath + "/" + currentLibrary);
2405 }
2406 
importLibrary(QString clc,QString destPath,QString name)2407 void LibraryWindow::importLibrary(QString clc, QString destPath, QString name)
2408 {
2409     packageManager->extractPackage(clc, destPath + "/" + name);
2410     _lastAdded = name;
2411     _sourceLastAdded = destPath + "/" + name;
2412 }
2413 
reloadOptions()2414 void LibraryWindow::reloadOptions()
2415 {
2416     comicsViewsManager->comicsView->updateConfig(settings);
2417 
2418     trayIconController->updateIconVisibility();
2419 }
2420 
currentPath()2421 QString LibraryWindow::currentPath()
2422 {
2423     return libraries.getPath(selectedLibrary->currentText());
2424 }
2425 
currentFolderPath()2426 QString LibraryWindow::currentFolderPath()
2427 {
2428     QString path;
2429 
2430     if (foldersView->selectionModel()->selectedRows().length() > 0)
2431         path = foldersModel->getFolderPath(foldersModelProxy->mapToSource(foldersView->currentIndex()));
2432     else
2433         path = foldersModel->getFolderPath(QModelIndex());
2434 
2435     QLOG_DEBUG() << "current folder path : " << QDir::cleanPath(currentPath() + path);
2436 
2437     return QDir::cleanPath(currentPath() + path);
2438 }
2439 
showExportComicsInfo()2440 void LibraryWindow::showExportComicsInfo()
2441 {
2442     exportComicsInfoDialog->source = currentPath() + "/.yacreaderlibrary/library.ydb";
2443     exportComicsInfoDialog->open();
2444 }
2445 
showImportComicsInfo()2446 void LibraryWindow::showImportComicsInfo()
2447 {
2448     importComicsInfoDialog->dest = currentPath() + "/.yacreaderlibrary/library.ydb";
2449     importComicsInfoDialog->open();
2450 }
2451 #include "startup.h"
2452 extern Startup *s;
closeEvent(QCloseEvent * event)2453 void LibraryWindow::closeEvent(QCloseEvent *event)
2454 {
2455     if (!trayIconController->handleCloseToTrayIcon(event)) {
2456         event->accept();
2457         closeApp();
2458     }
2459 }
2460 
prepareToCloseApp()2461 void LibraryWindow::prepareToCloseApp()
2462 {
2463     s->stop();
2464     settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry());
2465 
2466     comicsViewsManager->comicsView->close();
2467     sideBar->close();
2468 
2469     QApplication::instance()->processEvents();
2470 }
2471 
closeApp()2472 void LibraryWindow::closeApp()
2473 {
2474     prepareToCloseApp();
2475 
2476     qApp->exit(0);
2477 }
2478 
showNoLibrariesWidget()2479 void LibraryWindow::showNoLibrariesWidget()
2480 {
2481     disableAllActions();
2482     searchEdit->setDisabled(true);
2483     mainWidget->setCurrentIndex(1);
2484 }
2485 
showRootWidget()2486 void LibraryWindow::showRootWidget()
2487 {
2488 #ifndef Q_OS_MAC
2489     libraryToolBar->setDisabled(false);
2490 #endif
2491     searchEdit->setEnabled(true);
2492     mainWidget->setCurrentIndex(0);
2493 }
2494 
showImportingWidget()2495 void LibraryWindow::showImportingWidget()
2496 {
2497     disableAllActions();
2498     importWidget->clear();
2499 #ifndef Q_OS_MAC
2500     libraryToolBar->setDisabled(true);
2501 #endif
2502     searchEdit->setDisabled(true);
2503     mainWidget->setCurrentIndex(2);
2504 }
2505 
manageCreatingError(const QString & error)2506 void LibraryWindow::manageCreatingError(const QString &error)
2507 {
2508     QMessageBox::critical(this, tr("Error creating the library"), error);
2509 }
2510 
manageUpdatingError(const QString & error)2511 void LibraryWindow::manageUpdatingError(const QString &error)
2512 {
2513     QMessageBox::critical(this, tr("Error updating the library"), error);
2514 }
2515 
manageOpeningLibraryError(const QString & error)2516 void LibraryWindow::manageOpeningLibraryError(const QString &error)
2517 {
2518     QMessageBox::critical(this, tr("Error opening the library"), error);
2519 }
2520 
lessThanModelIndexRow(const QModelIndex & m1,const QModelIndex & m2)2521 bool lessThanModelIndexRow(const QModelIndex &m1, const QModelIndex &m2)
2522 {
2523     return m1.row() < m2.row();
2524 }
2525 
getSelectedComics()2526 QModelIndexList LibraryWindow::getSelectedComics()
2527 {
2528     //se fuerza a que haya almenos una fila seleccionada TODO comprobar se se puede forzar a la tabla a que lo haga automáticamente
2529     //avoid selection.count()==0 forcing selection in comicsView
2530     QModelIndexList selection = comicsViewsManager->comicsView->selectionModel()->selectedRows();
2531     QLOG_TRACE() << "selection count " << selection.length();
2532     std::sort(selection.begin(), selection.end(), lessThanModelIndexRow);
2533 
2534     if (selection.count() == 0) {
2535         comicsViewsManager->comicsView->selectIndex(0);
2536         selection = comicsViewsManager->comicsView->selectionModel()->selectedRows();
2537     }
2538     return selection;
2539 }
2540 
deleteComics()2541 void LibraryWindow::deleteComics()
2542 {
2543     //TODO
2544     if (!listsView->selectionModel()->selectedRows().isEmpty()) {
2545         deleteComicsFromList();
2546     } else {
2547         deleteComicsFromDisk();
2548     }
2549 }
2550 
deleteComicsFromDisk()2551 void LibraryWindow::deleteComicsFromDisk()
2552 {
2553     int ret = QMessageBox::question(this, tr("Delete comics"), tr("All the selected comics will be deleted from your disk. Are you sure?"), QMessageBox::Yes, QMessageBox::No);
2554 
2555     if (ret == QMessageBox::Yes) {
2556 
2557         QModelIndexList indexList = getSelectedComics();
2558 
2559         QList<ComicDB> comics = comicsModel->getComics(indexList);
2560 
2561         QList<QString> paths;
2562         QString libraryPath = currentPath();
2563         foreach (ComicDB comic, comics) {
2564             paths.append(libraryPath + comic.path);
2565             QLOG_TRACE() << comic.path;
2566             QLOG_TRACE() << comic.id;
2567             QLOG_TRACE() << comic.parentId;
2568         }
2569 
2570         auto remover = new ComicsRemover(indexList, paths, comics.at(0).parentId);
2571         const auto thread = new QThread(this);
2572         moveAndConnectRemoverToThread(remover, thread);
2573 
2574         comicsModel->startTransaction();
2575 
2576         connect(remover, SIGNAL(remove(int)), comicsModel, SLOT(remove(int)));
2577         connect(remover, SIGNAL(removeError()), this, SLOT(setRemoveError()));
2578         connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction()));
2579         connect(remover, SIGNAL(removedItemsFromFolder(qulonglong)), foldersModel, SLOT(updateFolderChildrenInfo(qulonglong)));
2580 
2581         connect(remover, SIGNAL(finished()), this, SLOT(checkEmptyFolder()));
2582         connect(remover, SIGNAL(finished()), this, SLOT(checkRemoveError()));
2583 
2584         thread->start();
2585     }
2586 }
2587 
deleteComicsFromList()2588 void LibraryWindow::deleteComicsFromList()
2589 {
2590     int ret = QMessageBox::question(this, tr("Remove comics"), tr("Comics will only be deleted from the current label/list. Are you sure?"), QMessageBox::Yes, QMessageBox::No);
2591 
2592     if (ret == QMessageBox::Yes) {
2593         QModelIndexList indexList = getSelectedComics();
2594         if (indexList.isEmpty())
2595             return;
2596 
2597         QModelIndex mi = listsModelProxy->mapToSource(listsView->currentIndex());
2598 
2599         ReadingListModel::TypeList typeList = (ReadingListModel::TypeList)mi.data(ReadingListModel::TypeListsRole).toInt();
2600 
2601         qulonglong id = mi.data(ReadingListModel::IDRole).toULongLong();
2602         switch (typeList) {
2603         case ReadingListModel::SpecialList:
2604             comicsModel->deleteComicsFromSpecialList(indexList, id);
2605             break;
2606         case ReadingListModel::Label:
2607             comicsModel->deleteComicsFromLabel(indexList, id);
2608             break;
2609         case ReadingListModel::ReadingList:
2610             comicsModel->deleteComicsFromReadingList(indexList, id);
2611             break;
2612         case ReadingListModel::Separator:
2613             break;
2614         }
2615     }
2616 }
2617 
showFoldersContextMenu(const QPoint & point)2618 void LibraryWindow::showFoldersContextMenu(const QPoint &point)
2619 {
2620     QModelIndex sourceMI = foldersModelProxy->mapToSource(foldersView->indexAt(point));
2621 
2622     bool isCompleted = sourceMI.data(FolderModel::CompletedRole).toBool();
2623     bool isRead = sourceMI.data(FolderModel::FinishedRole).toBool();
2624     bool isManga = sourceMI.data(FolderModel::MangaRole).toBool();
2625 
2626     QMenu menu;
2627     //QMenu * folderMenu = new QMenu(tr("Folder"));
2628     menu.addAction(openContainingFolderAction);
2629     menu.addAction(updateFolderAction);
2630     menu.addSeparator(); //-------------------------------
2631     if (isCompleted)
2632         menu.addAction(setFolderAsNotCompletedAction);
2633     else
2634         menu.addAction(setFolderAsCompletedAction);
2635     menu.addSeparator(); //-------------------------------
2636     if (isRead)
2637         menu.addAction(setFolderAsUnreadAction);
2638     else
2639         menu.addAction(setFolderAsReadAction);
2640     menu.addSeparator(); //-------------------------------
2641     if (isManga)
2642         menu.addAction(setFolderAsNormalAction);
2643     else
2644         menu.addAction(setFolderAsMangaAction);
2645 
2646     menu.exec(foldersView->mapToGlobal(point));
2647 }
2648 
2649 /*
2650 void LibraryWindow::showSocial()
2651 {
2652         socialDialog->move(this->mapToGlobal(QPoint(width()-socialDialog->width()-10, centralWidget()->pos().y()+10)));
2653 
2654         QModelIndexList indexList = getSelectedComics();
2655 
2656         ComicDB comic = dmCV->getComic(indexList.at(0));
2657 
2658         socialDialog->setComic(comic,currentPath());
2659         socialDialog->setHidden(false);
2660 }*/
2661 
libraryAlreadyExists(const QString & name)2662 void LibraryWindow::libraryAlreadyExists(const QString &name)
2663 {
2664     QMessageBox::information(this, tr("Library name already exists"), tr("There is another library with the name '%1'.").arg(name));
2665 }
2666 
importLibraryPackage()2667 void LibraryWindow::importLibraryPackage()
2668 {
2669     importLibraryDialog->open(libraries);
2670 }
2671 
updateComicsView(quint64 libraryId,const ComicDB & comic)2672 void LibraryWindow::updateComicsView(quint64 libraryId, const ComicDB &comic)
2673 {
2674     if (libraryId == (quint64)libraries.getId(selectedLibrary->currentText())) {
2675         comicsModel->reload(comic);
2676         comicsViewsManager->updateCurrentComicView();
2677     }
2678 }
2679