From ec57c8f9bd992786676baeb8364ab3b4732e3923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Tue, 19 Aug 2014 16:12:47 +0200 Subject: [PATCH] merged --- YACReader.desktop | 2 +- YACReader/YACReader.pri | 1 + YACReader/YACReader.pro | 2 +- YACReader/magnifying_glass.cpp | 63 +- YACReader/main_window_viewer.cpp | 497 +++++++---- YACReader/main_window_viewer.h | 23 +- YACReader/options_dialog.cpp | 1 + YACReader/shortcuts_dialog.cpp | 2 +- YACReader/viewer.cpp | 124 +-- YACReader/yacreader_images.qrc | 10 + YACReaderLibrary.desktop | 2 +- YACReaderLibrary/YACReaderLibrary.pro | 31 +- YACReaderLibrary/classic_comics_view.cpp | 243 ++++++ YACReaderLibrary/classic_comics_view.h | 51 ++ YACReaderLibrary/comics_view.cpp | 11 + YACReaderLibrary/comics_view.h | 47 ++ YACReaderLibrary/comics_view_transition.cpp | 74 ++ YACReaderLibrary/comics_view_transition.h | 31 + YACReaderLibrary/db/data_base_management.cpp | 4 +- YACReaderLibrary/db/tablemodel.cpp | 84 +- YACReaderLibrary/db/tablemodel.h | 10 +- YACReaderLibrary/db/treemodel.cpp | 70 +- YACReaderLibrary/db/treemodel.h | 2 + YACReaderLibrary/db_helper.cpp | 17 +- YACReaderLibrary/db_helper.h | 1 + YACReaderLibrary/empty_folder_widget.cpp | 89 ++ YACReaderLibrary/empty_folder_widget.h | 32 + YACReaderLibrary/grid_comics_view.cpp | 234 ++++++ YACReaderLibrary/grid_comics_view.h | 59 ++ YACReaderLibrary/images.qrc | 12 +- YACReaderLibrary/images_osx.qrc | 3 + YACReaderLibrary/images_win.qrc | 38 +- YACReaderLibrary/library_window.cpp | 779 +++++++++++------- YACReaderLibrary/library_window.h | 225 ++--- YACReaderLibrary/main.cpp | 5 +- YACReaderLibrary/options_dialog.cpp | 55 +- YACReaderLibrary/qml.qrc | 8 + YACReaderLibrary/qml/GridComicsView.qml | 295 +++++++ YACReaderLibrary/qml/YACReaderScrollView.qml | 336 ++++++++ YACReaderLibrary/qml/page-macosx.png | Bin 0 -> 171 bytes YACReaderLibrary/qml/page.png | Bin 0 -> 155 bytes YACReaderLibrary/qml/reading.png | Bin 0 -> 374 bytes YACReaderLibrary/qml/star-macosx.png | Bin 0 -> 288 bytes YACReaderLibrary/qml/star.png | Bin 0 -> 242 bytes YACReaderLibrary/qml/tick.png | Bin 0 -> 488 bytes YACReaderLibrary/qml_osx.qrc | 6 + YACReaderLibrary/qml_win.qrc | 6 + YACReaderLibrary/server/startup.cpp | 13 +- YACReaderLibrary/yacreader_local_server.cpp | 7 +- YACReaderLibrary/yacreader_local_server.h | 1 + YACReaderLibrary/yacreader_main_toolbar.cpp | 7 +- YACReaderLibrary/yacreader_main_toolbar.h | 3 + common/yacreader_flow_gl.cpp | 2 +- common/yacreader_global.cpp | 8 + common/yacreader_global.h | 8 + custom_widgets/yacreader_options_dialog.cpp | 11 + custom_widgets/yacreader_options_dialog.h | 6 +- custom_widgets/yacreader_search_line_edit.cpp | 2 +- images/accept_shortcut.png | Bin 0 -> 204 bytes images/clear_shortcut.png | Bin 0 -> 200 bytes images/empty_folder.png | Bin 0 -> 2515 bytes images/flow_to_grid.gif | Bin 0 -> 124025 bytes images/grid_to_flow.gif | Bin 0 -> 129647 bytes images/shortcuts_group_comics.png | Bin 0 -> 276 bytes images/shortcuts_group_folders.png | Bin 0 -> 157 bytes images/shortcuts_group_general.png | Bin 0 -> 319 bytes images/shortcuts_group_libraries.png | Bin 0 -> 164 bytes images/shortcuts_group_mglass.png | Bin 0 -> 351 bytes images/shortcuts_group_page.png | Bin 0 -> 162 bytes images/shortcuts_group_reading.png | Bin 0 -> 179 bytes images/shortcuts_group_visualization.png | Bin 0 -> 320 bytes shortcuts_management/actions_groups_model.cpp | 80 ++ shortcuts_management/actions_groups_model.h | 44 + .../actions_shortcuts_model.cpp | 106 +++ .../actions_shortcuts_model.h | 38 + .../edit_shortcut_item_delegate.cpp | 145 ++++ .../edit_shortcut_item_delegate.h | 48 ++ .../edit_shortcuts_dialog.cpp | 95 +++ shortcuts_management/edit_shortcuts_dialog.h | 33 + shortcuts_management/shortcuts_management.pri | 16 + shortcuts_management/shortcuts_manager.cpp | 112 +++ shortcuts_management/shortcuts_manager.h | 127 +++ 82 files changed, 3744 insertions(+), 753 deletions(-) create mode 100644 YACReaderLibrary/classic_comics_view.cpp create mode 100644 YACReaderLibrary/classic_comics_view.h create mode 100644 YACReaderLibrary/comics_view.cpp create mode 100644 YACReaderLibrary/comics_view.h create mode 100644 YACReaderLibrary/comics_view_transition.cpp create mode 100644 YACReaderLibrary/comics_view_transition.h create mode 100644 YACReaderLibrary/empty_folder_widget.cpp create mode 100644 YACReaderLibrary/empty_folder_widget.h create mode 100644 YACReaderLibrary/grid_comics_view.cpp create mode 100644 YACReaderLibrary/grid_comics_view.h create mode 100644 YACReaderLibrary/qml.qrc create mode 100644 YACReaderLibrary/qml/GridComicsView.qml create mode 100644 YACReaderLibrary/qml/YACReaderScrollView.qml create mode 100644 YACReaderLibrary/qml/page-macosx.png create mode 100644 YACReaderLibrary/qml/page.png create mode 100644 YACReaderLibrary/qml/reading.png create mode 100644 YACReaderLibrary/qml/star-macosx.png create mode 100644 YACReaderLibrary/qml/star.png create mode 100644 YACReaderLibrary/qml/tick.png create mode 100644 YACReaderLibrary/qml_osx.qrc create mode 100644 YACReaderLibrary/qml_win.qrc create mode 100644 images/accept_shortcut.png create mode 100644 images/clear_shortcut.png create mode 100644 images/empty_folder.png create mode 100644 images/flow_to_grid.gif create mode 100644 images/grid_to_flow.gif create mode 100644 images/shortcuts_group_comics.png create mode 100644 images/shortcuts_group_folders.png create mode 100644 images/shortcuts_group_general.png create mode 100644 images/shortcuts_group_libraries.png create mode 100644 images/shortcuts_group_mglass.png create mode 100644 images/shortcuts_group_page.png create mode 100644 images/shortcuts_group_reading.png create mode 100644 images/shortcuts_group_visualization.png create mode 100644 shortcuts_management/actions_groups_model.cpp create mode 100644 shortcuts_management/actions_groups_model.h create mode 100644 shortcuts_management/actions_shortcuts_model.cpp create mode 100644 shortcuts_management/actions_shortcuts_model.h create mode 100644 shortcuts_management/edit_shortcut_item_delegate.cpp create mode 100644 shortcuts_management/edit_shortcut_item_delegate.h create mode 100644 shortcuts_management/edit_shortcuts_dialog.cpp create mode 100644 shortcuts_management/edit_shortcuts_dialog.h create mode 100644 shortcuts_management/shortcuts_management.pri create mode 100644 shortcuts_management/shortcuts_manager.cpp create mode 100644 shortcuts_management/shortcuts_manager.h diff --git a/YACReader.desktop b/YACReader.desktop index ddd79076..20c5f201 100644 --- a/YACReader.desktop +++ b/YACReader.desktop @@ -8,5 +8,5 @@ Terminal=false Type=Application StartupNotify=true Categories=Graphics;Viewer; -MimeType=application/x-cbz;application/x-cbr;application/x-cbt;application/x-cb7; +MimeType=application/x-cbz;application/x-cbr;application/x-cbt;application/x-cb7;application/x-pdf;application/x-zip;application/x-rar;application/x-7z;inode/directory; X-Desktop-File-Install-Version=0.22 diff --git a/YACReader/YACReader.pri b/YACReader/YACReader.pri index f4c3788d..4d7da37b 100644 --- a/YACReader/YACReader.pri +++ b/YACReader/YACReader.pri @@ -134,6 +134,7 @@ SOURCES += $$PWD/../common/comic.cpp \ include($$PWD/../custom_widgets/custom_widgets_yacreader.pri) include($$PWD/../compressed_archive/wrapper.pri) +include($$PWD/../shortcuts_management/shortcuts_management.pri) RESOURCES += $$PWD/yacreader_images.qrc \ $$PWD/yacreader_files.qrc diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 24a05ce0..e8746938 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -6,7 +6,7 @@ TARGET = YACReader DEPENDPATH += . \ release -DEFINES += NOMINMAX +DEFINES += NOMINMAX YACREADER unix:!macx{ QMAKE_CXXFLAGS += -std=c++11 diff --git a/YACReader/magnifying_glass.cpp b/YACReader/magnifying_glass.cpp index 0ff09aa7..c86f202e 100644 --- a/YACReader/magnifying_glass.cpp +++ b/YACReader/magnifying_glass.cpp @@ -1,6 +1,7 @@ #include "magnifying_glass.h" #include "viewer.h" #include "configuration.h" +#include "shortcuts_manager.h" #include @@ -244,26 +245,48 @@ void MagnifyingGlass::widthDown() void MagnifyingGlass::keyPressEvent(QKeyEvent *event) { bool validKey = false; - switch (event->key()) - { - case Qt::Key_Plus: - sizeUp(); - validKey = true; - break; - case Qt::Key_Minus: - sizeDown(); - validKey = true; - break; - case Qt::Key_Underscore: - zoomOut(); - validKey = true; - break; - case Qt::Key_Asterisk: - zoomIn(); - validKey = true; - break; - } - updateImage(); + + int _key = event->key(); + Qt::KeyboardModifiers modifiers = event->modifiers(); + + if(modifiers & Qt::ShiftModifier) + _key |= Qt::SHIFT; + if (modifiers & Qt::ControlModifier) + _key |= Qt::CTRL; + if (modifiers & Qt::MetaModifier) + _key |= Qt::META; + if (modifiers & Qt::AltModifier) + _key |= Qt::ALT; + + QKeySequence key(_key); + + if (key == ShortcutsManager::getShortcutsManager().getShortcut(SIZE_UP_MGLASS_ACTION_Y)) + { + sizeUp(); + validKey = true; + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(SIZE_DOWN_MGLASS_ACTION_Y)) + { + sizeDown(); + validKey = true; + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_IN_MGLASS_ACTION_Y)) + { + zoomIn(); + validKey = true; + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_OUT_MGLASS_ACTION_Y)) + { + zoomOut(); + validKey = true; + } + if(validKey) + { + updateImage(); event->setAccepted(true); + } } diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 036d8667..67928f87 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -17,6 +17,8 @@ #include "yacreader_local_client.h" #include "yacreader_global.h" +#include "edit_shortcuts_dialog.h" +#include "shortcuts_manager.h" #include #include @@ -87,19 +89,19 @@ MainWindowViewer::~MainWindowViewer() delete openNextComicAction; delete prevAction; delete nextAction; - delete adjustHeight; - delete adjustWidth; + delete adjustHeightAction; + delete adjustWidthAction; delete leftRotationAction; delete rightRotationAction; delete doublePageAction; - delete goToPage; + delete goToPageAction; delete optionsAction; delete helpAboutAction; - delete showMagnifyingGlass; - delete setBookmark; - delete showBookmarks; + delete showMagnifyingGlassAction; + delete setBookmarkAction; + delete showBookmarksAction; delete showShorcutsAction; - delete showInfo; + delete showInfoAction; delete closeAction; delete showDictionaryAction; delete alwaysOnTopAction; @@ -163,8 +165,12 @@ void MainWindowViewer::setupUI() optionsDialog->restoreOptions(settings); shortcutsDialog = new ShortcutsDialog(this); + editShortcutsDialog = new EditShortcutsDialog(this); + connect(optionsDialog,SIGNAL(editShortcuts()),editShortcutsDialog,SLOT(show())); createActions(); + setUpShortcutsManagement(); + createToolBars(); setWindowTitle("YACReader"); @@ -194,181 +200,216 @@ void MainWindowViewer::setupUI() void MainWindowViewer::createActions() { - openAction = new QAction(tr("&Open"),this); - openAction->setShortcut(tr("O")); - openAction->setIcon(QIcon(":/images/viewer_toolbar/open.png")); - openAction->setToolTip(tr("Open a comic")); - connect(openAction, SIGNAL(triggered()), this, SLOT(open())); + openAction = new QAction(tr("&Open"),this); + openAction->setIcon(QIcon(":/images/viewer_toolbar/open.png")); + openAction->setToolTip(tr("Open a comic")); + openAction->setData(OPEN_ACTION_Y); + openAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_ACTION_Y)); + connect(openAction, SIGNAL(triggered()), this, SLOT(open())); - openFolderAction = new QAction(tr("Open Folder"),this); - openFolderAction->setShortcut(tr("Ctrl+O")); - openFolderAction->setIcon(QIcon(":/images/viewer_toolbar/openFolder.png")); - openFolderAction->setToolTip(tr("Open image folder")); - connect(openFolderAction, SIGNAL(triggered()), this, SLOT(openFolder())); + openFolderAction = new QAction(tr("Open Folder"),this); + openFolderAction->setIcon(QIcon(":/images/viewer_toolbar/openFolder.png")); + openFolderAction->setToolTip(tr("Open image folder")); + openFolderAction->setData(OPEN_FOLDER_ACTION_Y); + openFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_FOLDER_ACTION_Y)); + connect(openFolderAction, SIGNAL(triggered()), this, SLOT(openFolder())); - saveImageAction = new QAction(tr("Save"),this); - saveImageAction->setIcon(QIcon(":/images/viewer_toolbar/save.png")); - saveImageAction->setToolTip(tr("Save current page")); - saveImageAction->setDisabled(true); - connect(saveImageAction,SIGNAL(triggered()),this,SLOT(saveImage())); + saveImageAction = new QAction(tr("Save"),this); + saveImageAction->setIcon(QIcon(":/images/viewer_toolbar/save.png")); + saveImageAction->setToolTip(tr("Save current page")); + saveImageAction->setDisabled(true); + saveImageAction->setData(SAVE_IMAGE_ACTION_Y); + saveImageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_IMAGE_ACTION_Y)); + connect(saveImageAction,SIGNAL(triggered()),this,SLOT(saveImage())); - openPreviousComicAction = new QAction(tr("Previous Comic"),this); - openPreviousComicAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.png")); - openPreviousComicAction->setShortcut(Qt::CTRL + Qt::Key_Left); - openPreviousComicAction->setToolTip(tr("Open previous comic")); - openPreviousComicAction->setDisabled(true); - connect(openPreviousComicAction,SIGNAL(triggered()),this,SLOT(openPreviousComic())); + openPreviousComicAction = new QAction(tr("Previous Comic"),this); + openPreviousComicAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.png")); + openPreviousComicAction->setToolTip(tr("Open previous comic")); + openPreviousComicAction->setDisabled(true); + openPreviousComicAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); + openPreviousComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); + connect(openPreviousComicAction,SIGNAL(triggered()),this,SLOT(openPreviousComic())); - openNextComicAction = new QAction(tr("Next Comic"),this); - openNextComicAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.png")); - openNextComicAction->setShortcut(Qt::CTRL + Qt::Key_Right); - openNextComicAction->setToolTip(tr("Open next comic")); - openNextComicAction->setDisabled(true); - connect(openNextComicAction,SIGNAL(triggered()),this,SLOT(openNextComic())); + openNextComicAction = new QAction(tr("Next Comic"),this); + openNextComicAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.png")); + openNextComicAction->setToolTip(tr("Open next comic")); + openNextComicAction->setDisabled(true); + openNextComicAction->setData(OPEN_NEXT_COMIC_ACTION_Y); + openNextComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); + connect(openNextComicAction,SIGNAL(triggered()),this,SLOT(openNextComic())); - prevAction = new QAction(tr("&Previous"),this); - prevAction->setIcon(QIcon(":/images/viewer_toolbar/previous.png")); - prevAction->setShortcut(Qt::Key_Left); - prevAction->setShortcutContext(Qt::WidgetShortcut); - prevAction->setToolTip(tr("Go to previous page")); - prevAction->setDisabled(true); - connect(prevAction, SIGNAL(triggered()),viewer,SLOT(prev())); + prevAction = new QAction(tr("&Previous"),this); + prevAction->setIcon(QIcon(":/images/viewer_toolbar/previous.png")); + prevAction->setShortcutContext(Qt::WidgetShortcut); + prevAction->setToolTip(tr("Go to previous page")); + prevAction->setDisabled(true); + prevAction->setData(PREV_ACTION_Y); + prevAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(PREV_ACTION_Y)); + connect(prevAction, SIGNAL(triggered()),viewer,SLOT(prev())); - nextAction = new QAction(tr("&Next"),this); - nextAction->setIcon(QIcon(":/images/viewer_toolbar/next.png")); - nextAction->setShortcut(Qt::Key_Right); - nextAction->setShortcutContext(Qt::WidgetShortcut); - nextAction->setToolTip(tr("Go to next page")); + nextAction = new QAction(tr("&Next"),this); + nextAction->setIcon(QIcon(":/images/viewer_toolbar/next.png")); + nextAction->setShortcutContext(Qt::WidgetShortcut); + nextAction->setToolTip(tr("Go to next page")); nextAction->setDisabled(true); + nextAction->setData(NEXT_ACTION_Y); + nextAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(NEXT_ACTION_Y)); connect(nextAction, SIGNAL(triggered()),viewer,SLOT(next())); - adjustHeight = new QAction(tr("Fit Height"),this); - adjustHeight->setIcon(QIcon(":/images/viewer_toolbar/toHeight.png")); + adjustHeightAction = new QAction(tr("Fit Height"),this); + adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.png")); //adjustWidth->setCheckable(true); - adjustHeight->setDisabled(true); - adjustHeight->setChecked(Configuration::getConfiguration().getAdjustToWidth()); - adjustHeight->setToolTip(tr("Fit image to height")); + adjustHeightAction->setDisabled(true); + adjustHeightAction->setChecked(Configuration::getConfiguration().getAdjustToWidth()); + adjustHeightAction->setToolTip(tr("Fit image to height")); //adjustWidth->setIcon(QIcon(":/images/fitWidth.png")); - connect(adjustHeight, SIGNAL(triggered()),this,SLOT(fitToHeight())); + adjustHeightAction->setData(ADJUST_HEIGHT_ACTION_Y); + adjustHeightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_HEIGHT_ACTION_Y)); + connect(adjustHeightAction, SIGNAL(triggered()),this,SLOT(fitToHeight())); - adjustWidth = new QAction(tr("Fit Width"),this); - adjustWidth->setIcon(QIcon(":/images/viewer_toolbar/toWidth.png")); + adjustWidthAction = new QAction(tr("Fit Width"),this); + adjustWidthAction->setIcon(QIcon(":/images/viewer_toolbar/toWidth.png")); //adjustWidth->setCheckable(true); - adjustWidth->setDisabled(true); - adjustWidth->setChecked(Configuration::getConfiguration().getAdjustToWidth()); - adjustWidth->setToolTip(tr("Fit image to width")); + adjustWidthAction->setDisabled(true); + adjustWidthAction->setChecked(Configuration::getConfiguration().getAdjustToWidth()); + adjustWidthAction->setToolTip(tr("Fit image to width")); //adjustWidth->setIcon(QIcon(":/images/fitWidth.png")); - connect(adjustWidth, SIGNAL(triggered()),this,SLOT(fitToWidth())); + adjustWidthAction->setData(ADJUST_WIDTH_ACTION_Y); + adjustWidthAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_WIDTH_ACTION_Y)); + connect(adjustWidthAction, SIGNAL(triggered()),this,SLOT(fitToWidth())); leftRotationAction = new QAction(tr("Rotate image to the left"),this); - leftRotationAction->setShortcut(tr("L")); leftRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateL.png")); leftRotationAction->setDisabled(true); + leftRotationAction->setData(LEFT_ROTATION_ACTION_Y); + leftRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(LEFT_ROTATION_ACTION_Y)); connect(leftRotationAction, SIGNAL(triggered()),viewer,SLOT(rotateLeft())); rightRotationAction = new QAction(tr("Rotate image to the right"),this); - rightRotationAction->setShortcut(tr("R")); rightRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateR.png")); rightRotationAction->setDisabled(true); + rightRotationAction->setData(RIGHT_ROTATION_ACTION_Y); + rightRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RIGHT_ROTATION_ACTION_Y)); connect(rightRotationAction, SIGNAL(triggered()),viewer,SLOT(rotateRight())); doublePageAction = new QAction(tr("Double page mode"),this); doublePageAction->setToolTip(tr("Switch to double page mode")); - doublePageAction->setShortcut(tr("D")); doublePageAction->setIcon(QIcon(":/images/viewer_toolbar/doublePage.png")); doublePageAction->setDisabled(true); doublePageAction->setCheckable(true); doublePageAction->setChecked(Configuration::getConfiguration().getDoublePage()); + doublePageAction->setData(DOUBLE_PAGE_ACTION_Y); + doublePageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DOUBLE_PAGE_ACTION_Y)); connect(doublePageAction, SIGNAL(triggered()),viewer,SLOT(doublePageSwitch())); - goToPage = new QAction(tr("Go To"),this); - goToPage->setShortcut(tr("G")); - goToPage->setIcon(QIcon(":/images/viewer_toolbar/goto.png")); - goToPage->setDisabled(true); - goToPage->setToolTip(tr("Go to page ...")); - connect(goToPage, SIGNAL(triggered()),viewer,SLOT(showGoToDialog())); + goToPageAction = new QAction(tr("Go To"),this); + goToPageAction->setIcon(QIcon(":/images/viewer_toolbar/goto.png")); + goToPageAction->setDisabled(true); + goToPageAction->setToolTip(tr("Go to page ...")); + goToPageAction->setData(GO_TO_PAGE_ACTION_Y); + goToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_PAGE_ACTION_Y)); + connect(goToPageAction, SIGNAL(triggered()),viewer,SLOT(showGoToDialog())); optionsAction = new QAction(tr("Options"),this); - optionsAction->setShortcut(tr("C")); optionsAction->setToolTip(tr("YACReader options")); + optionsAction->setData(OPTIONS_ACTION_Y); + optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_Y)); optionsAction->setIcon(QIcon(":/images/viewer_toolbar/options.png")); connect(optionsAction, SIGNAL(triggered()),optionsDialog,SLOT(show())); helpAboutAction = new QAction(tr("Help"),this); helpAboutAction->setToolTip(tr("Help, About YACReader")); - helpAboutAction->setShortcut(Qt::Key_F1); helpAboutAction->setIcon(QIcon(":/images/viewer_toolbar/help.png")); + helpAboutAction->setData(HELP_ABOUT_ACTION_Y); + helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_Y)); connect(helpAboutAction, SIGNAL(triggered()),had,SLOT(show())); - showMagnifyingGlass = new QAction(tr("Magnifying glass"),this); - showMagnifyingGlass->setToolTip(tr("Switch Magnifying glass")); - showMagnifyingGlass->setShortcut(tr("Z")); - showMagnifyingGlass->setIcon(QIcon(":/images/viewer_toolbar/magnifyingGlass.png")); - showMagnifyingGlass->setDisabled(true); - showMagnifyingGlass->setCheckable(true); - connect(showMagnifyingGlass, SIGNAL(triggered()),viewer,SLOT(magnifyingGlassSwitch())); + showMagnifyingGlassAction = new QAction(tr("Magnifying glass"),this); + showMagnifyingGlassAction->setToolTip(tr("Switch Magnifying glass")); + showMagnifyingGlassAction->setIcon(QIcon(":/images/viewer_toolbar/magnifyingGlass.png")); + showMagnifyingGlassAction->setDisabled(true); + showMagnifyingGlassAction->setCheckable(true); + showMagnifyingGlassAction->setData(SHOW_MAGNIFYING_GLASS_ACTION_Y); + showMagnifyingGlassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_MAGNIFYING_GLASS_ACTION_Y)); + connect(showMagnifyingGlassAction, SIGNAL(triggered()),viewer,SLOT(magnifyingGlassSwitch())); - setBookmark = new QAction(tr("Set bookmark"),this); - setBookmark->setToolTip(tr("Set a bookmark on the current page")); - setBookmark->setShortcut(Qt::CTRL+Qt::Key_M); - setBookmark->setIcon(QIcon(":/images/viewer_toolbar/bookmark.png")); - setBookmark->setDisabled(true); - setBookmark->setCheckable(true); - connect(setBookmark,SIGNAL(triggered (bool)),viewer,SLOT(setBookmark(bool))); - connect(viewer,SIGNAL(pageAvailable(bool)),setBookmark,SLOT(setEnabled(bool))); - connect(viewer,SIGNAL(pageIsBookmark(bool)),setBookmark,SLOT(setChecked(bool))); + setBookmarkAction = new QAction(tr("Set bookmark"),this); + setBookmarkAction->setToolTip(tr("Set a bookmark on the current page")); + setBookmarkAction->setIcon(QIcon(":/images/viewer_toolbar/bookmark.png")); + setBookmarkAction->setDisabled(true); + setBookmarkAction->setCheckable(true); + setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y); + setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y)); + connect(setBookmarkAction,SIGNAL(triggered (bool)),viewer,SLOT(setBookmarkAction(bool))); + connect(viewer,SIGNAL(pageAvailable(bool)),setBookmarkAction,SLOT(setEnabled(bool))); + connect(viewer,SIGNAL(pageIsBookmark(bool)),setBookmarkAction,SLOT(setChecked(bool))); - showBookmarks = new QAction(tr("Show bookmarks"),this); - showBookmarks->setToolTip(tr("Show the bookmarks of the current comic")); - showBookmarks->setShortcut(tr("M")); - showBookmarks->setIcon(QIcon(":/images/viewer_toolbar/showBookmarks.png")); - showBookmarks->setDisabled(true); - connect(showBookmarks, SIGNAL(triggered()),viewer->getBookmarksDialog(),SLOT(show())); + showBookmarksAction = new QAction(tr("Show bookmarks"),this); + showBookmarksAction->setToolTip(tr("Show the bookmarks of the current comic")); + showBookmarksAction->setIcon(QIcon(":/images/viewer_toolbar/showBookmarks.png")); + showBookmarksAction->setDisabled(true); + showBookmarksAction->setData(SHOW_BOOKMARKS_ACTION_Y); + showBookmarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_BOOKMARKS_ACTION_Y)); + connect(showBookmarksAction, SIGNAL(triggered()),viewer->getBookmarksDialog(),SLOT(show())); showShorcutsAction = new QAction(tr("Show keyboard shortcuts"), this ); showShorcutsAction->setIcon(QIcon(":/images/viewer_toolbar/shortcuts.png")); + showShorcutsAction->setData(SHOW_SHORCUTS_ACTION_Y); + showShorcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_SHORCUTS_ACTION_Y)); connect(showShorcutsAction, SIGNAL(triggered()),shortcutsDialog,SLOT(show())); - showInfo = new QAction(tr("Show Info"),this); - showInfo->setShortcut(tr("I")); - showInfo->setIcon(QIcon(":/images/viewer_toolbar/info.png")); - showInfo->setDisabled(true); - connect(showInfo, SIGNAL(triggered()),viewer,SLOT(informationSwitch())); + showInfoAction = new QAction(tr("Show Info"),this); + showInfoAction->setIcon(QIcon(":/images/viewer_toolbar/info.png")); + showInfoAction->setDisabled(true); + showInfoAction->setData(SHOW_INFO_ACTION_Y); + showInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_INFO_ACTION_Y)); + connect(showInfoAction, SIGNAL(triggered()),viewer,SLOT(informationSwitch())); closeAction = new QAction(tr("Close"),this); - closeAction->setShortcut(Qt::Key_Escape); closeAction->setIcon(QIcon(":/images/viewer_toolbar/close.png")); + closeAction->setData(CLOSE_ACTION_Y); + closeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CLOSE_ACTION_Y)); connect(closeAction,SIGNAL(triggered()),this,SLOT(close())); showDictionaryAction = new QAction(tr("Show Dictionary"),this); - showDictionaryAction->setShortcut(Qt::Key_T); showDictionaryAction->setIcon(QIcon(":/images/viewer_toolbar/translator.png")); //showDictionaryAction->setCheckable(true); showDictionaryAction->setDisabled(true); + showDictionaryAction->setData(SHOW_DICTIONARY_ACTION_Y); + showDictionaryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_DICTIONARY_ACTION_Y)); connect(showDictionaryAction,SIGNAL(triggered()),viewer,SLOT(translatorSwitch())); + //deprecated alwaysOnTopAction = new QAction(tr("Always on top"),this); - alwaysOnTopAction->setShortcut(Qt::Key_Q); alwaysOnTopAction->setIcon(QIcon(":/images/alwaysOnTop.png")); alwaysOnTopAction->setCheckable(true); alwaysOnTopAction->setDisabled(true); alwaysOnTopAction->setChecked(Configuration::getConfiguration().getAlwaysOnTop()); + alwaysOnTopAction->setData(ALWAYS_ON_TOP_ACTION_Y); + alwaysOnTopAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ALWAYS_ON_TOP_ACTION_Y)); connect(alwaysOnTopAction,SIGNAL(triggered()),this,SLOT(alwaysOnTopSwitch())); adjustToFullSizeAction = new QAction(tr("Show full size"),this); - adjustToFullSizeAction->setShortcut(Qt::Key_W); adjustToFullSizeAction->setIcon(QIcon(":/images/viewer_toolbar/full.png")); adjustToFullSizeAction->setCheckable(true); adjustToFullSizeAction->setDisabled(true); adjustToFullSizeAction->setChecked(Configuration::getConfiguration().getAdjustToFullSize()); + adjustToFullSizeAction->setData(ADJUST_TO_FULL_SIZE_ACTION_Y); + adjustToFullSizeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_TO_FULL_SIZE_ACTION_Y)); connect(adjustToFullSizeAction,SIGNAL(triggered()),this,SLOT(adjustToFullSizeSwitch())); showFlowAction = new QAction(tr("Show go to flow"),this); - showFlowAction->setShortcut(Qt::Key_S); showFlowAction->setIcon(QIcon(":/images/viewer_toolbar/flow.png")); showFlowAction->setDisabled(true); + showFlowAction->setData(SHOW_FLOW_ACTION_Y); + showFlowAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_FLOW_ACTION_Y)); connect(showFlowAction,SIGNAL(triggered()),viewer,SLOT(goToFlowSwitch())); + + showEditShortcutsAction = new QAction(tr("Edit shortcuts"),this); + showEditShortcutsAction->setData(SHOW_EDIT_SHORTCUTS_ACTION_Y); + showEditShortcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_EDIT_SHORTCUTS_ACTION_Y)); + connect(showEditShortcutsAction,SIGNAL(triggered()),editShortcutsDialog,SLOT(show())); } void MainWindowViewer::createToolBars() @@ -399,7 +440,7 @@ void MainWindowViewer::createToolBars() #endif comicToolBar->addAction(prevAction); comicToolBar->addAction(nextAction); - comicToolBar->addAction(goToPage); + comicToolBar->addAction(goToPageAction); //#ifndef Q_OS_MAC // comicToolBar->addSeparator(); @@ -440,7 +481,7 @@ void MainWindowViewer::createToolBars() ); menu->addAction(sliderAction); QToolButton * tb2 = new QToolButton(); - tb2->addAction(adjustWidth); + tb2->addAction(adjustWidthAction); tb2->setMenu(menu); connect(sliderAction,SIGNAL(fitToWidthRatioChanged(float)),viewer,SLOT(updateFitToWidthRatio(float))); @@ -449,9 +490,9 @@ void MainWindowViewer::createToolBars() //tb2->addAction(); tb2->setPopupMode(QToolButton::MenuButtonPopup); - tb2->setDefaultAction(adjustWidth); + tb2->setDefaultAction(adjustWidthAction); comicToolBar->addWidget(tb2); - comicToolBar->addAction(adjustHeight); + comicToolBar->addAction(adjustHeightAction); comicToolBar->addAction(adjustToFullSizeAction); comicToolBar->addAction(leftRotationAction); comicToolBar->addAction(rightRotationAction); @@ -462,15 +503,15 @@ void MainWindowViewer::createToolBars() #else comicToolBar->addSeparator(); #endif - comicToolBar->addAction(showMagnifyingGlass); + comicToolBar->addAction(showMagnifyingGlassAction); #ifdef Q_OS_MAC comicToolBar->addWidget(new MacToolBarSeparator); #else comicToolBar->addSeparator(); #endif - comicToolBar->addAction(setBookmark); - comicToolBar->addAction(showBookmarks); + comicToolBar->addAction(setBookmarkAction); + comicToolBar->addAction(showBookmarksAction); #ifdef Q_OS_MAC comicToolBar->addWidget(new MacToolBarSeparator); @@ -479,7 +520,7 @@ void MainWindowViewer::createToolBars() #endif comicToolBar->addAction(showDictionaryAction); comicToolBar->addAction(showFlowAction); - comicToolBar->addAction(showInfo); + comicToolBar->addAction(showInfoAction); #ifdef Q_OS_MAC comicToolBar->addWidget(new MacToolBarSeparator); @@ -505,27 +546,28 @@ void MainWindowViewer::createToolBars() viewer->addAction(prevAction); viewer->addAction(nextAction); - viewer->addAction(goToPage); - viewer->addAction(adjustHeight); - viewer->addAction(adjustWidth); + viewer->addAction(goToPageAction); + viewer->addAction(adjustHeightAction); + viewer->addAction(adjustWidthAction); viewer->addAction(adjustToFullSizeAction); viewer->addAction(leftRotationAction); viewer->addAction(rightRotationAction); YACReader::addSperator(viewer); - viewer->addAction(showMagnifyingGlass); + viewer->addAction(showMagnifyingGlassAction); YACReader::addSperator(viewer); - viewer->addAction(setBookmark); - viewer->addAction(showBookmarks); + viewer->addAction(setBookmarkAction); + viewer->addAction(showBookmarksAction); YACReader::addSperator(viewer); viewer->addAction(showDictionaryAction); viewer->addAction(showFlowAction); - viewer->addAction(showInfo); + viewer->addAction(showInfoAction); YACReader::addSperator(viewer); viewer->addAction(showShorcutsAction); + viewer->addAction(showEditShortcutsAction); viewer->addAction(optionsAction); viewer->addAction(helpAboutAction); YACReader::addSperator(viewer); @@ -727,18 +769,18 @@ void MainWindowViewer::enableActions() saveImageAction->setDisabled(false); prevAction->setDisabled(false); nextAction->setDisabled(false); - adjustHeight->setDisabled(false); - adjustWidth->setDisabled(false); - goToPage->setDisabled(false); + adjustHeightAction->setDisabled(false); + adjustWidthAction->setDisabled(false); + goToPageAction->setDisabled(false); //alwaysOnTopAction->setDisabled(false); leftRotationAction->setDisabled(false); rightRotationAction->setDisabled(false); - showMagnifyingGlass->setDisabled(false); + showMagnifyingGlassAction->setDisabled(false); doublePageAction->setDisabled(false); adjustToFullSizeAction->setDisabled(false); //setBookmark->setDisabled(false); - showBookmarks->setDisabled(false); - showInfo->setDisabled(false); //TODO enable goTo and showInfo (or update) when numPages emited + showBookmarksAction->setDisabled(false); + showInfoAction->setDisabled(false); //TODO enable goTo and showInfo (or update) when numPages emited showDictionaryAction->setDisabled(false); showFlowAction->setDisabled(false); } @@ -747,18 +789,18 @@ void MainWindowViewer::disableActions() saveImageAction->setDisabled(true); prevAction->setDisabled(true); nextAction->setDisabled(true); - adjustHeight->setDisabled(true); - adjustWidth->setDisabled(true); - goToPage->setDisabled(true); + adjustHeightAction->setDisabled(true); + adjustWidthAction->setDisabled(true); + goToPageAction->setDisabled(true); //alwaysOnTopAction->setDisabled(true); leftRotationAction->setDisabled(true); rightRotationAction->setDisabled(true); - showMagnifyingGlass->setDisabled(true); + showMagnifyingGlassAction->setDisabled(true); doublePageAction->setDisabled(true); adjustToFullSizeAction->setDisabled(true); - setBookmark->setDisabled(true); - showBookmarks->setDisabled(true); - showInfo->setDisabled(true); //TODO enable goTo and showInfo (or update) when numPages emited + setBookmarkAction->setDisabled(true); + showBookmarksAction->setDisabled(true); + showInfoAction->setDisabled(true); //TODO enable goTo and showInfo (or update) when numPages emited openPreviousComicAction->setDisabled(true); openNextComicAction->setDisabled(true); showDictionaryAction->setDisabled(true); @@ -767,28 +809,38 @@ void MainWindowViewer::disableActions() void MainWindowViewer::keyPressEvent(QKeyEvent *event) { - //TODO remove unused keys - switch (event->key()) - { - case Qt::Key_Escape: - this->close(); - break; - case Qt::Key_F: - toggleFullScreen(); - break; - case Qt::Key_H: - toggleToolBars(); - break; - case Qt::Key_O: - open(); - break; - case Qt::Key_A: - changeFit(); - break; - default: - QWidget::keyPressEvent(event); - break; - } + //TODO remove unused keys + int _key = event->key(); + Qt::KeyboardModifiers modifiers = event->modifiers(); + + if(modifiers & Qt::ShiftModifier) + _key |= Qt::SHIFT; + if (modifiers & Qt::ControlModifier) + _key |= Qt::CTRL; + if (modifiers & Qt::MetaModifier) + _key |= Qt::META; + if (modifiers & Qt::AltModifier) + _key |= Qt::ALT; + + QKeySequence key(_key); + + if (key == ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_FULL_SCREEN_ACTION_Y)) + { + toggleFullScreen(); + event->accept(); + } + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_TOOL_BARS_ACTION_Y)) + { + toggleToolBars(); + event->accept(); + } + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(CHANGE_FIT_ACTION_Y)) + { + changeFit(); + event->accept(); + } + else + QWidget::keyPressEvent(event); } void MainWindowViewer::mouseDoubleClickEvent ( QMouseEvent * event ) @@ -887,7 +939,7 @@ void MainWindowViewer::checkNewVersion() QTimer * tT = new QTimer; tT->setSingleShot(true); connect(tT, SIGNAL(timeout()), versionChecker, SLOT(get())); - //versionChecker->get(); //TODÓ + //versionChecker->get(); //TOD� tT->start(100); conf.setLastVersionCheck(current); @@ -913,6 +965,147 @@ void MainWindowViewer::processReset() disableActions(); } +void MainWindowViewer::setUpShortcutsManagement() +{ + //actions holder + QObject * orphanActions = new QObject; + + QList allActions; + QList tmpList; + + + editShortcutsDialog->addActionsGroup(tr("Comics"),QIcon(":/images/shortcuts_group_comics.png"), + tmpList = QList() + << openAction + << openFolderAction + << saveImageAction + << openPreviousComicAction + << openNextComicAction); + + allActions << tmpList; + + //keys without actions (General) + QAction * toggleFullScreenAction = new QAction(tr("Toggle fullscreen mode"),orphanActions); + toggleFullScreenAction->setData(TOGGLE_FULL_SCREEN_ACTION_Y); + toggleFullScreenAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_FULL_SCREEN_ACTION_Y)); + + QAction * toggleToolbarsAction = new QAction(tr("Hide/show toolbar"),orphanActions); + toggleToolbarsAction->setData(TOGGLE_TOOL_BARS_ACTION_Y); + toggleToolbarsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_TOOL_BARS_ACTION_Y)); + + editShortcutsDialog->addActionsGroup(tr("General"),QIcon(":/images/shortcuts_group_general.png"), + tmpList = QList() + << optionsAction + << helpAboutAction + << showShorcutsAction + << showInfoAction + << closeAction + << showDictionaryAction + << showFlowAction + << toggleFullScreenAction + << toggleToolbarsAction + << showEditShortcutsAction); + + allActions << tmpList; + + //keys without actions (MGlass) + QAction * sizeUpMglassAction = new QAction(tr("Size up magnifying glass"),orphanActions); + sizeUpMglassAction->setData(SIZE_UP_MGLASS_ACTION_Y); + sizeUpMglassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SIZE_UP_MGLASS_ACTION_Y)); + + QAction * sizeDownMglassAction = new QAction(tr("Size down magnifying glass"),orphanActions); + sizeDownMglassAction->setData(SIZE_DOWN_MGLASS_ACTION_Y); + sizeDownMglassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SIZE_DOWN_MGLASS_ACTION_Y)); + + QAction * zoomInMglassAction = new QAction(tr("Zoom in magnifying glass"),orphanActions); + zoomInMglassAction->setData(ZOOM_IN_MGLASS_ACTION_Y); + zoomInMglassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_IN_MGLASS_ACTION_Y)); + + QAction * zoomOutMglassAction = new QAction(tr("Zoom out magnifying glass"),orphanActions); + zoomOutMglassAction->setData(ZOOM_OUT_MGLASS_ACTION_Y); + zoomOutMglassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_OUT_MGLASS_ACTION_Y)); + + editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"),QIcon(":/images/shortcuts_group_mglass.png"), + tmpList = QList() + << showMagnifyingGlassAction + << sizeUpMglassAction + << sizeDownMglassAction + << zoomInMglassAction + << zoomOutMglassAction); + + allActions << tmpList; + + //keys without actions + QAction * toggleFitToScreenAction = new QAction(tr("Toggle between fit to width and fit to height"),orphanActions); + toggleFitToScreenAction->setData(CHANGE_FIT_ACTION_Y); + toggleFitToScreenAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CHANGE_FIT_ACTION_Y)); + + editShortcutsDialog->addActionsGroup(tr("Page adjustement"),QIcon(":/images/shortcuts_group_page.png"), + tmpList = QList() + << adjustHeightAction + << adjustWidthAction + << toggleFitToScreenAction + << leftRotationAction + << rightRotationAction + << doublePageAction + << adjustToFullSizeAction); + + allActions << tmpList; + + QAction * autoScrollForwardAction = new QAction(tr("Autoscroll down"),orphanActions); + autoScrollForwardAction->setData(AUTO_SCROLL_FORWARD_ACTION_Y); + autoScrollForwardAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(AUTO_SCROLL_FORWARD_ACTION_Y)); + + QAction * autoScrollBackwardAction = new QAction(tr("Autoscroll up"),orphanActions); + autoScrollBackwardAction->setData(AUTO_SCROLL_BACKWARD_ACTION_Y); + autoScrollBackwardAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(AUTO_SCROLL_BACKWARD_ACTION_Y)); + + QAction * moveDownAction = new QAction(tr("Move down"),orphanActions); + moveDownAction->setData(MOVE_DOWN_ACTION_Y); + moveDownAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(MOVE_DOWN_ACTION_Y)); + + QAction * moveUpAction = new QAction(tr("Move up"),orphanActions); + moveUpAction->setData(MOVE_UP_ACTION_Y); + moveUpAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(MOVE_UP_ACTION_Y)); + + QAction * moveLeftAction = new QAction(tr("Move left"),orphanActions); + moveLeftAction->setData(MOVE_LEFT_ACTION_Y); + moveLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(MOVE_LEFT_ACTION_Y)); + + QAction * moveRightAction = new QAction(tr("Move right"),orphanActions); + moveRightAction->setData(MOVE_RIGHT_ACTION_Y); + moveRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(MOVE_RIGHT_ACTION_Y)); + + QAction * goToFirstPageAction = new QAction(tr("Go to the first page"),orphanActions); + goToFirstPageAction->setData(GO_TO_FIRST_PAGE_ACTION_Y); + goToFirstPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_FIRST_PAGE_ACTION_Y)); + + QAction * goToLastPageAction = new QAction(tr("Go to the last page"),orphanActions); + goToLastPageAction->setData(GO_TO_LAST_PAGE_ACTION_Y); + goToLastPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_LAST_PAGE_ACTION_Y)); + + editShortcutsDialog->addActionsGroup(tr("Reading"),QIcon(":/images/shortcuts_group_reading.png"), + tmpList = QList() + << nextAction + << prevAction + << setBookmarkAction + << showBookmarksAction + << autoScrollForwardAction + << autoScrollBackwardAction + << moveDownAction + << moveUpAction + << moveLeftAction + << moveRightAction + << goToFirstPageAction + << goToLastPageAction + << goToPageAction); + + allActions << tmpList; + + ShortcutsManager::getShortcutsManager().registerActions(allActions); + +} + void MainWindowViewer::changeFit() { Configuration & conf = Configuration::getConfiguration(); diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index 758e2207..10ab75ff 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -18,6 +18,7 @@ class HelpAboutDialog; class HttpVersionChecker; class ShortcutsDialog; class YACReaderSliderAction; +class EditShortcutsDialog; class MainWindowViewer : public QMainWindow { @@ -52,6 +53,7 @@ class YACReaderSliderAction; void fitToHeight(); void checkNewVersion(); void processReset(); + void setUpShortcutsManagement(); /*void viewComic(); void prev(); void next(); @@ -72,6 +74,7 @@ class YACReaderSliderAction; OptionsDialog * optionsDialog; HelpAboutDialog * had; ShortcutsDialog * shortcutsDialog; + EditShortcutsDialog * editShortcutsDialog; //! ToolBars QToolBar *comicToolBar; @@ -84,17 +87,17 @@ class YACReaderSliderAction; QAction *openNextComicAction; QAction *nextAction; QAction *prevAction; - QAction *adjustWidth; - QAction *adjustHeight; - QAction *goToPage; + QAction *adjustWidthAction; + QAction *adjustHeightAction; + QAction *goToPageAction; QAction *optionsAction; QAction *helpAboutAction; - QAction *showMagnifyingGlass; - QAction *setBookmark; - QAction *showBookmarks; + QAction *showMagnifyingGlassAction; + QAction *setBookmarkAction; + QAction *showBookmarksAction; QAction *leftRotationAction; QAction *rightRotationAction; - QAction *showInfo; + QAction *showInfoAction; QAction *closeAction; QAction *doublePageAction; QAction *showShorcutsAction; @@ -103,6 +106,8 @@ class YACReaderSliderAction; QAction *adjustToFullSizeAction; QAction *showFlowAction; + QAction *showEditShortcutsAction; + YACReaderSliderAction * sliderAction; HttpVersionChecker * versionChecker; @@ -115,8 +120,8 @@ class YACReaderSliderAction; void getSiblingComics(QString path,QString currentComic); //! Manejadores de evento: - void keyPressEvent(QKeyEvent *event); - //void resizeEvent(QResizeEvent * event); + void keyPressEvent(QKeyEvent *event); + //void resizeEvent(QResizeEvent * event); void mouseDoubleClickEvent ( QMouseEvent * event ); void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent *event); diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 83a2de20..37d25792 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -113,6 +113,7 @@ OptionsDialog::OptionsDialog(QWidget * parent) layoutGeneral->addWidget(slideSizeBox); layoutGeneral->addWidget(fitBox); layoutGeneral->addWidget(colorBox); + layoutGeneral->addWidget(shortcutsBox); layoutGeneral->addStretch(); layoutFlow->addWidget(sw); layoutFlow->addWidget(gl); diff --git a/YACReader/shortcuts_dialog.cpp b/YACReader/shortcuts_dialog.cpp index 8c7fe908..dd7441cf 100644 --- a/YACReader/shortcuts_dialog.cpp +++ b/YACReader/shortcuts_dialog.cpp @@ -51,7 +51,7 @@ ShortcutsDialog::ShortcutsDialog(QWidget * parent) setLayout(imgMainLayout); - setFixedSize(QSize(700,500)); + setFixedSize(QSize(700,500)); QFile f(":/files/shortcuts.html"); f.open(QIODevice::ReadOnly); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index d90c0f95..10812be8 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -12,6 +12,8 @@ #include "page_label_widget.h" #include "notifications_label_widget.h" #include "comic_db.h" +#include "shortcuts_manager.h" + #include @@ -367,62 +369,72 @@ void Viewer::scrollUp() void Viewer::keyPressEvent(QKeyEvent *event) { - if(render->hasLoadedComic()) - { - if(goToFlow->isVisible() && event->key()!=Qt::Key_S) - QCoreApplication::sendEvent(goToFlow,event); - else - switch (event->key()) - { - case Qt::Key_Space: - posByStep = height()/numScrollSteps; - nextPos=verticalScrollBar()->sliderPosition()+static_cast((height()*0.80)); - scrollDown(); - break; - case Qt::Key_B: - posByStep = height()/numScrollSteps; - nextPos=verticalScrollBar()->sliderPosition()-static_cast((height()*0.80)); - scrollUp(); - break; - case Qt::Key_S: - goToFlowSwitch(); - break; - case Qt::Key_T: - translatorSwitch(); - break; - case Qt::Key_Down: - /*if(verticalScrollBar()->sliderPosition()==verticalScrollBar()->maximum()) - next(); - else*/ - QAbstractScrollArea::keyPressEvent(event); - emit backgroundChanges(); - break; - case Qt::Key_Up: - /*if(verticalScrollBar()->sliderPosition()==verticalScrollBar()->minimum()) - prev(); - else*/ - QAbstractScrollArea::keyPressEvent(event); - emit backgroundChanges(); - break; - case Qt::Key_Home: - goTo(0); - break; - case Qt::Key_End: - goTo(this->render->numPages()-1); - break; - default: - QAbstractScrollArea::keyPressEvent(event); - break; - } - if(mglass->isVisible()) - switch(event->key()) - { - case Qt::Key_Plus: case Qt::Key_Minus: case Qt::Key_Underscore: case Qt::Key_Asterisk: - QCoreApplication::sendEvent(mglass,event); - } - } - else - QAbstractScrollArea::keyPressEvent(event); + if(render->hasLoadedComic()) + { + int _key = event->key(); + Qt::KeyboardModifiers modifiers = event->modifiers(); + + if(modifiers & Qt::ShiftModifier) + _key |= Qt::SHIFT; + if (modifiers & Qt::ControlModifier) + _key |= Qt::CTRL; + if (modifiers & Qt::MetaModifier) + _key |= Qt::META; + if (modifiers & Qt::AltModifier) + _key |= Qt::ALT; + + QKeySequence key(_key); + /*if(goToFlow->isVisible() && event->key()!=Qt::Key_S) + QCoreApplication::sendEvent(goToFlow,event); + else*/ + + if (key == ShortcutsManager::getShortcutsManager().getShortcut(AUTO_SCROLL_FORWARD_ACTION_Y)) + { + posByStep = height()/numScrollSteps; + nextPos=verticalScrollBar()->sliderPosition()+static_cast((height()*0.80)); + scrollDown(); + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(AUTO_SCROLL_BACKWARD_ACTION_Y)) + { + posByStep = height()/numScrollSteps; + nextPos=verticalScrollBar()->sliderPosition()-static_cast((height()*0.80)); + scrollUp(); + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(MOVE_DOWN_ACTION_Y) || + key == ShortcutsManager::getShortcutsManager().getShortcut(MOVE_UP_ACTION_Y) || + key == ShortcutsManager::getShortcutsManager().getShortcut(MOVE_LEFT_ACTION_Y) || + key == ShortcutsManager::getShortcutsManager().getShortcut(MOVE_RIGHT_ACTION_Y)) + { + QAbstractScrollArea::keyPressEvent(event); + emit backgroundChanges(); + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_FIRST_PAGE_ACTION_Y)) + { + goTo(0); + } + + else if (key == ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_LAST_PAGE_ACTION_Y)) + { + goTo(this->render->numPages()-1); + } + + else + QAbstractScrollArea::keyPressEvent(event); + + if(mglass->isVisible() && (key == ShortcutsManager::getShortcutsManager().getShortcut(SIZE_UP_MGLASS_ACTION_Y) || + key == ShortcutsManager::getShortcutsManager().getShortcut(SIZE_DOWN_MGLASS_ACTION_Y) || + key == ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_IN_MGLASS_ACTION_Y) || + key == ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_OUT_MGLASS_ACTION_Y))) + { + QCoreApplication::sendEvent(mglass,event); + } + + } + else + QAbstractScrollArea::keyPressEvent(event); } void Viewer::wheelEvent(QWheelEvent * event) diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index 3defdcfa..ca8f9714 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -73,5 +73,15 @@ ../images/dropDownArrow.png ../images/translatorSearch.png ../images/speaker.png + ../images/clear_shortcut.png + ../images/accept_shortcut.png + ../images/shortcuts_group_comics.png + ../images/shortcuts_group_folders.png + ../images/shortcuts_group_general.png + ../images/shortcuts_group_libraries.png + ../images/shortcuts_group_mglass.png + ../images/shortcuts_group_page.png + ../images/shortcuts_group_reading.png + ../images/shortcuts_group_visualization.png diff --git a/YACReaderLibrary.desktop b/YACReaderLibrary.desktop index 38551ad7..76ee3432 100644 --- a/YACReaderLibrary.desktop +++ b/YACReaderLibrary.desktop @@ -8,5 +8,5 @@ Terminal=false Type=Application StartupNotify=true Categories=Graphics;Viewer; -MimeType=application/x-cbz;application/x-cbr;application/x-cbt;application/x-cb7; +MimeType= X-Desktop-File-Install-Version=0.22 diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index a97ade55..bb4f8252 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -13,7 +13,7 @@ INCLUDEPATH += ../common \ ./comic_vine \ ./comic_vine/model -DEFINES += SERVER_RELEASE NOMINMAX +DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY win32 { @@ -34,7 +34,6 @@ CONFIG -= embed_manifest_exe } unix:!macx{ -QMAKE_CXXFLAGS += -std=c++11 isEqual(QT_MAJOR_VERSION, 5) { INCLUDEPATH += /usr/include/poppler/qt5 @@ -67,6 +66,10 @@ CONFIG += objective_c } +unix{ +QMAKE_CXXFLAGS += -std=c++11 +} + #CONFIG += release CONFIG -= flat QT += sql network opengl script @@ -113,6 +116,10 @@ HEADERS += comic_flow.h \ ../common/http_worker.h \ yacreader_libraries.h \ ../common/exit_check.h \ + comics_view.h \ + classic_comics_view.h \ + empty_folder_widget.h + SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ @@ -156,6 +163,10 @@ SOURCES += comic_flow.cpp \ ../common/yacreader_global.cpp \ yacreader_libraries.cpp \ ../common/exit_check.cpp \ + comics_view.cpp \ + classic_comics_view.cpp \ + empty_folder_widget.cpp + include(./server/server.pri) @@ -163,6 +174,7 @@ include(../custom_widgets/custom_widgets_yacreaderlibrary.pri) include(../compressed_archive/wrapper.pri) include(./comic_vine/comic_vine.pri) include(../QsLog/QsLog.pri) +include(../shortcuts_management/shortcuts_management.pri) RESOURCES += images.qrc files.qrc win32:RESOURCES += images_win.qrc @@ -186,6 +198,21 @@ TRANSLATIONS = yacreaderlibrary_es.ts \ isEqual(QT_MAJOR_VERSION, 5) { Release:DESTDIR = ../release5 Debug:DESTDIR = ../debug5 + +#QML/GridView +QT += quick qml + +HEADERS += grid_comics_view.h \ + comics_view_transition.h + +SOURCES += grid_comics_view.cpp \ + comics_view_transition.cpp + +RESOURCES += qml.qrc +win32:RESOURCES += qml_win.qrc +unix:!macx:RESOURCES += qml_win.qrc +macx:RESOURCES += qml_osx.qrc + } else { Release:DESTDIR = ../release Debug:DESTDIR = ../debug diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp new file mode 100644 index 00000000..48444658 --- /dev/null +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -0,0 +1,243 @@ +#include "classic_comics_view.h" + +#include "yacreader_table_view.h" + +#include "comic_flow_widget.h" +#include "QsLog.h" + +ClassicComicsView::ClassicComicsView(QWidget *parent) + :ComicsView(parent) +{ + QHBoxLayout * layout = new QHBoxLayout; + + settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor + settings->beginGroup("libraryConfig"); + //FLOW----------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + if(QGLFormat::hasOpenGL() && (settings->value(USE_OPEN_GL).toBool() == true)) + comicFlow = new ComicFlowWidgetGL(0); + else + comicFlow = new ComicFlowWidgetSW(0); + + comicFlow->updateConfig(settings); + comicFlow->setFocusPolicy(Qt::StrongFocus); + comicFlow->setShowMarks(true); + setFocusProxy(comicFlow); + + comicFlow->setFocus(Qt::OtherFocusReason); + + comicFlow->setContextMenuPolicy(Qt::ActionsContextMenu); + + //TODO!!! set actions.... + //comicFlow->addAction(toggleFullScreenAction); + //comicFlow->addAction(openComicAction); + + //END FLOW---- + + + //layout----------------------------------------------- + sVertical = new QSplitter(Qt::Vertical); //spliter derecha + + sVertical->addWidget(comicFlow); + comics = new QWidget; + QVBoxLayout * comicsLayout = new QVBoxLayout; + comicsLayout->setSpacing(0); + comicsLayout->setContentsMargins(0,0,0,0); + //TODO ComicsView:(set toolbar) comicsLayout->addWidget(editInfoToolBar); + + tableView = new YACReaderTableView; + tableView->verticalHeader()->hide(); + tableView->setFocusPolicy(Qt::StrongFocus); + comicsLayout->addWidget(tableView); + comics->setLayout(comicsLayout); + sVertical->addWidget(comics); + + //config-------------------------------------------------- + if(settings->contains(COMICS_VIEW_HEADERS)) + tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); + + //connections--------------------------------------------- + connect(tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex))); + connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateTableView(int))); + connect(tableView, SIGNAL(comicRated(int,QModelIndex)), this, SIGNAL(comicRated(int,QModelIndex))); + connect(comicFlow, SIGNAL(selected(uint)), this, SIGNAL(selected(uint))); + connect(tableView->horizontalHeader(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(saveTableHeadersStatus())); + + layout->addWidget(sVertical); + setLayout(layout); + + layout->setMargin(0); + +#ifdef Q_OS_MAC + sVertical->setCollapsible(1,false); +#endif +} + +void ClassicComicsView::setToolBar(QToolBar *toolBar) +{ + static_cast(comics->layout())->insertWidget(0,toolBar); +} + +void ClassicComicsView::setModel(TableModel *model) +{ + + ComicsView::setModel(model); + + if(model == NULL) + { + comicFlow->clear(); + } + else + { + connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)), this, SLOT(applyModelChanges(QModelIndex,QModelIndex,QVector))); + connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(removeItemsFromFlow(QModelIndex,int,int))); + + tableView->setModel(model); + + tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + #if QT_VERSION >= 0x050000 + tableView->horizontalHeader()->setSectionsMovable(true); + #else + tableView->horizontalHeader()->setMovable(true); + #endif + //TODO parametrizar la configuración de las columnas + for(int i = 0;ihorizontalHeader()->count();i++) + tableView->horizontalHeader()->hideSection(i); + + tableView->horizontalHeader()->showSection(TableModel::Number); + tableView->horizontalHeader()->showSection(TableModel::Title); + tableView->horizontalHeader()->showSection(TableModel::FileName); + tableView->horizontalHeader()->showSection(TableModel::NumPages); + tableView->horizontalHeader()->showSection(TableModel::Hash); //Size is part of the Hash...TODO add Columns::Size to Columns + tableView->horizontalHeader()->showSection(TableModel::ReadColumn); + tableView->horizontalHeader()->showSection(TableModel::CurrentPage); + tableView->horizontalHeader()->showSection(TableModel::Rating); + + //debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles) + //así que se ecala la primera vez y después se deja el control al usuario. + //if(!settings->contains(COMICS_VIEW_HEADERS)) + tableView->resizeColumnsToContents(); + tableView->horizontalHeader()->setStretchLastSection(true); + + QStringList paths = model->getPaths(model->getCurrentPath());//TODO ComicsView: get currentpath from somewhere currentPath()); + comicFlow->setImagePaths(paths); + comicFlow->setMarks(model->getReadList()); + //comicFlow->setFocus(Qt::OtherFocusReason); + } + + if(settings->contains(COMICS_VIEW_HEADERS)) + tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); + + +} + +void ClassicComicsView::setCurrentIndex(const QModelIndex &index) +{ + tableView->setCurrentIndex(index); + //TODO ComicsView: scroll comicFlow to index +} + +QModelIndex ClassicComicsView::currentIndex() +{ + return tableView->currentIndex(); +} + +QItemSelectionModel *ClassicComicsView::selectionModel() +{ + return tableView->selectionModel(); +} + +void ClassicComicsView::scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint) +{ + comicFlow->setCenterIndex(mi.row()); +} + +void ClassicComicsView::toFullScreen() +{ + comicFlow->hide(); + comicFlow->setCenterIndex(comicFlow->centerIndex()); + comics->hide(); + + //showFullScreen() //parent windows + + comicFlow->show(); + comicFlow->setFocus(Qt::OtherFocusReason); +} + +void ClassicComicsView::toNormal() +{ + comicFlow->hide(); + comicFlow->setCenterIndex(comicFlow->centerIndex()); + comicFlow->render(); + comics->show(); + comicFlow->show(); +} + +void ClassicComicsView::updateConfig(QSettings *settings) +{ + comicFlow->updateConfig(settings); +} + +void ClassicComicsView::setItemActions(const QList &actions) +{ + tableView->addActions(actions); +} + +void ClassicComicsView::setViewActions(const QList &actions) +{ + comicFlow->addActions(actions); +} + +void ClassicComicsView::selectAll() +{ + tableView->selectAll(); +} + +void ClassicComicsView::setShowMarks(bool show) +{ + comicFlow->setShowMarks(show); +} + +void ClassicComicsView::centerComicFlow(const QModelIndex & mi) +{ + comicFlow->showSlide(mi.row()); + comicFlow->setFocus(Qt::OtherFocusReason); +} + +void ClassicComicsView::updateTableView(int i) +{ + QModelIndex mi = model->index(i,2); + tableView->setCurrentIndex(mi); + tableView->scrollTo(mi,QAbstractItemView::EnsureVisible); +} + +void ClassicComicsView::saveTableHeadersStatus() +{ + settings->setValue(COMICS_VIEW_HEADERS,tableView->horizontalHeader()->saveState()); +} + +void ClassicComicsView::applyModelChanges(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); + if(roles.contains(TableModel::ReadColumnRole)) + { + comicFlow->setMarks(model->getReadList()); + comicFlow->updateMarks(); + } +} + +void ClassicComicsView::removeItemsFromFlow(const QModelIndex &parent, int from, int to) +{ + Q_UNUSED(parent); + for(int i = from; i<=to; i++) + comicFlow->remove(i); +} + +void ClassicComicsView::closeEvent(QCloseEvent *event) +{ + saveTableHeadersStatus(); + ComicsView::closeEvent(event); +} + diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h new file mode 100644 index 00000000..9f8c71a6 --- /dev/null +++ b/YACReaderLibrary/classic_comics_view.h @@ -0,0 +1,51 @@ +#ifndef CLASSIC_COMICS_VIEW_H +#define CLASSIC_COMICS_VIEW_H + +#include "comics_view.h" + +#include +#include + +class YACReaderTableView; +class QSplitter; +class ComicFlowWidget; +class QToolBar; +class TableModel; + +class ClassicComicsView : public ComicsView +{ + Q_OBJECT +public: + ClassicComicsView(QWidget *parent = 0); + void setToolBar(QToolBar * toolBar); + void setModel(TableModel *model); + void setCurrentIndex(const QModelIndex &index); + QModelIndex currentIndex(); + QItemSelectionModel * selectionModel(); + void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ); + void toFullScreen(); + void toNormal(); + void updateConfig(QSettings * settings); + void setItemActions(const QList & actions); + void setViewActions(const QList & actions); + +public slots: + void centerComicFlow(const QModelIndex & mi); + void updateTableView(int i); + void saveTableHeadersStatus(); + void applyModelChanges(const QModelIndex & topLeft,const QModelIndex & bottomRight,const QVector & roles); + void removeItemsFromFlow(const QModelIndex & parent, int from, int to); + //ComicsView + void setShowMarks(bool show); + void selectAll(); + +private: + YACReaderTableView * tableView; + QWidget *comics; + QSplitter * sVertical; + ComicFlowWidget * comicFlow; + QSettings * settings; + void closeEvent ( QCloseEvent * event ); +}; + +#endif // CLASSIC_COMICS_VIEW_H diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp new file mode 100644 index 00000000..5c5e7725 --- /dev/null +++ b/YACReaderLibrary/comics_view.cpp @@ -0,0 +1,11 @@ +#include "comics_view.h" + +ComicsView::ComicsView(QWidget *parent) : + QWidget(parent),model(NULL) +{ +} + +void ComicsView::setModel(TableModel *m) +{ + model = m; +} diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h new file mode 100644 index 00000000..5ae8e485 --- /dev/null +++ b/YACReaderLibrary/comics_view.h @@ -0,0 +1,47 @@ +#ifndef COMICS_VIEW_H +#define COMICS_VIEW_H + +#include + +#include "tablemodel.h" +#include +#include +#include +#include + +class YACReaderTableView; +class QSplitter; +class ComicFlowWidget; +class QToolBar; +class TableModel; +class ComicsView : public QWidget +{ + Q_OBJECT +public: + explicit ComicsView(QWidget *parent = 0); + virtual void setToolBar(QToolBar * toolBar) = 0; + virtual void setModel(TableModel *model); + virtual void setCurrentIndex(const QModelIndex &index) = 0; + virtual QModelIndex currentIndex() = 0; + virtual QItemSelectionModel * selectionModel() = 0; + virtual void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ) = 0; + virtual void toFullScreen() = 0; + virtual void toNormal() = 0; + virtual void updateConfig(QSettings * settings) = 0; + //Actions for tableviews + virtual void setItemActions(const QList & actions) = 0; + //actions for visual-oriented views + virtual void setViewActions(const QList & actions) = 0; + +signals: + void selected(unsigned int); + void comicRated(int,QModelIndex); +public slots: + virtual void setShowMarks(bool show) = 0; + virtual void selectAll() = 0; +protected: + TableModel * model; + +}; + +#endif // COMICS_VIEW_H diff --git a/YACReaderLibrary/comics_view_transition.cpp b/YACReaderLibrary/comics_view_transition.cpp new file mode 100644 index 00000000..3e2fdd12 --- /dev/null +++ b/YACReaderLibrary/comics_view_transition.cpp @@ -0,0 +1,74 @@ +#include "comics_view_transition.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "yacreader_global.h" + +ComicsViewTransition::ComicsViewTransition(QWidget *parent) : + QWidget(parent),movie(0) +{ + QVBoxLayout * layout = new QVBoxLayout; + + settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); + settings->beginGroup("libraryConfig"); + + movieLabel = new QLabel("Placeholder"); + movieLabel->setAlignment(Qt::AlignCenter); + QLabel * textLabel = new QLabel("Switching comics view"); + textLabel->setAlignment(Qt::AlignCenter); + textLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); + //movieLabel->setFixedSize(450,350); + + layout->addSpacing(100); + layout->addWidget(movieLabel); + layout->addSpacing(20); + layout->addWidget(textLabel); + layout->addStretch(); + layout->setMargin(0); + layout->setSpacing(0); + + setContentsMargins(0,0,0,0); + + setStyleSheet("QWidget {background:#2A2A2A}"); + + //QSizePolicy sp(); + setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding ); + //movieLabel->setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding ); + setLayout(layout); +} + +QSize ComicsViewTransition::sizeHint() +{ + return QSize(450,350); +} + +void ComicsViewTransition::startMovie() +{ + if(movie) + delete movie; + + if(settings->value(COMICS_VIEW_STATUS) == YACReader::Flow) + movie = new QMovie(":/images/flow_to_grid.gif"); + else + movie = new QMovie(":/images/grid_to_flow.gif"); + + connect(movie,SIGNAL(finished()),this,SIGNAL(transitionFinished())); + //connect(movie,SIGNAL(finished()),movie,SLOT(deleteLater()); + movie->setSpeed(200); + movie->jumpToFrame(0); + movieLabel->setMovie(movie); + + QTimer::singleShot(100,movie,SLOT(start())); +} + +void ComicsViewTransition::paintEvent(QPaintEvent *) +{ + QPainter painter (this); + painter.fillRect(0,0,width(),height(),QColor("#2A2A2A")); +} diff --git a/YACReaderLibrary/comics_view_transition.h b/YACReaderLibrary/comics_view_transition.h new file mode 100644 index 00000000..ed8c55ba --- /dev/null +++ b/YACReaderLibrary/comics_view_transition.h @@ -0,0 +1,31 @@ +#ifndef COMICS_VIEW_TRANSITION_H +#define COMICS_VIEW_TRANSITION_H + +#include + +class QMovie; +class QSettings; +class QLabel; + +class ComicsViewTransition : public QWidget +{ + Q_OBJECT +public: + explicit ComicsViewTransition(QWidget *parent = 0); + QSize sizeHint(); + +signals: + void transitionFinished(); + +public slots: + void startMovie(); + +protected: + QMovie * movie; + QSettings * settings; + QLabel * movieLabel; + + void paintEvent(QPaintEvent *); +}; + +#endif // COMICS_VIEW_TRANSITION_H diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 244634db..1b0ce7c9 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -210,7 +210,7 @@ bool DataBaseManagement::createTables(QSqlDatabase & database) //queryDBInfo.finish(); QSqlQuery query("INSERT INTO db_info (version) " - "VALUES ('"VERSION"')",database); + "VALUES ('" VERSION "')",database); //query.finish(); } @@ -245,7 +245,7 @@ void DataBaseManagement::exportComicsInfo(QString source, QString dest) queryComicsInfo.exec();*/ QSqlQuery query("INSERT INTO dest.db_info (version) " - "VALUES ('"VERSION"')",destDB); + "VALUES ('" VERSION "')",destDB); //query.finish(); QSqlQuery exportData(destDB); diff --git a/YACReaderLibrary/db/tablemodel.cpp b/YACReaderLibrary/db/tablemodel.cpp index e04bed06..8987176f 100644 --- a/YACReaderLibrary/db/tablemodel.cpp +++ b/YACReaderLibrary/db/tablemodel.cpp @@ -15,7 +15,7 @@ TableModel::TableModel(QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent) { connect(this,SIGNAL(beforeReset()),this,SIGNAL(modelAboutToBeReset())); connect(this,SIGNAL(reset()),this,SIGNAL(modelReset())); @@ -23,7 +23,7 @@ TableModel::TableModel(QObject *parent) //! [0] TableModel::TableModel( QSqlQuery &sqlquery, QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent) { setupModelData(sqlquery); } @@ -46,6 +46,27 @@ int TableModel::columnCount(const QModelIndex &parent) const } //! [2] +QHash TableModel::roleNames() const { + QHash roles; + + roles[NumberRole] = "number"; + roles[TitleRole] = "title"; + roles[FileNameRole] = "file_name"; + roles[NumPagesRole] = "num_pages"; + roles[IdRole] = "id"; + roles[Parent_IdRole] = "parent_id"; + roles[PathRole] = "path"; + roles[HashRole] = "hash"; + roles[ReadColumnRole] = "read_column"; + roles[IsBisRole] = "is_bis"; + roles[CurrentPageRole] = "current_page"; + roles[RatingRole] = "rating"; + roles[HasBeenOpenedRole] = "has_been_opened"; + roles[CoverPathRole] = "cover_path"; + + return roles; +} + //! [3] QVariant TableModel::data(const QModelIndex &index, int role) const { @@ -84,10 +105,28 @@ QVariant TableModel::data(const QModelIndex &index, int role) const //TODO check here if any view is asking for TableModel::Roles //these roles will be used from QML/GridView - if (role != Qt::DisplayRole) - return QVariant(); - TableItem *item = static_cast(index.internalPointer()); + + if (role == NumberRole) + return item->data(Number); + else if (role == TitleRole) + return item->data(Title).isNull()?item->data(FileName):item->data(Title); + else if (role == RatingRole) + return item->data(Rating); + else if (role == CoverPathRole) + return "file:///"+_databasePath+"/covers/"+item->data(Hash).toString()+".jpg"; + else if (role == NumPagesRole) + return item->data(NumPages); + else if (role == CurrentPageRole) + return item->data(CurrentPage); + else if (role == ReadColumnRole) + return item->data(ReadColumn).toBool(); + else if (role == HasBeenOpenedRole) + return item->data(TableModel::HasBeenOpened); + + if (role != Qt::DisplayRole) + return QVariant(); + if(index.column() == TableModel::Hash) return QString::number(item->data(index.column()).toString().right(item->data(index.column()).toString().length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb"; if(index.column() == TableModel::ReadColumn) @@ -265,7 +304,9 @@ void TableModel::setupModelData(unsigned long long int folderId,const QString & db.close(); QSqlDatabase::removeDatabase(_databasePath); endResetModel(); - //f.close(); + + if(_data.length()==0) + emit isEmpty(); } QString TableModel::getComicPath(QModelIndex mi) @@ -467,7 +508,7 @@ QVector TableModel::setComicsRead(QList l db.close(); QSqlDatabase::removeDatabase(_databasePath); - emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::CurrentPage+1)); + emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::HasBeenOpened),QVector() << ReadColumnRole << CurrentPageRole << HasBeenOpenedRole); return getReadList(); } @@ -553,10 +594,10 @@ void TableModel::remove(ComicDB * comic, int row) endRemoveRows(); } -ComicDB TableModel::getComic(int row) +/*ComicDB TableModel::getComic(int row) { return getComic(index(row,0)); -} +}*/ void TableModel::remove(int row) { @@ -580,8 +621,8 @@ void TableModel::reload(const ComicDB & comic) } row++; } - if(found) - emit dataChanged(index(row,TableModel::CurrentPage),index(row,TableModel::CurrentPage)); + if(found) + emit dataChanged(index(row,ReadColumn),index(row,HasBeenOpened), QVector() << ReadColumnRole << CurrentPageRole << HasBeenOpenedRole); } void TableModel::resetComicRating(const QModelIndex &mi) @@ -600,27 +641,6 @@ void TableModel::resetComicRating(const QModelIndex &mi) QSqlDatabase::removeDatabase(_databasePath); } -QHash TableModel::roleNames() -{ - QHash roles; - - roles[NumberRole] = "number"; - roles[TitleRole] = "title"; - roles[FileNameRole] = "file_name"; - roles[NumPagesRole] = "num_pages"; - roles[IdRole] = "id"; - roles[Parent_IdRole] = "parent_id"; - roles[PathRole] = "path"; - roles[HashRole] = "hash"; - roles[ReadColumnRole] = "read"; - roles[IsBisRole] = "is_bis"; - roles[CurrentPageRole] = "current_page"; - roles[RatingRole] = "rating"; - roles[HasBeenOpenedRole] = "has_been_opened"; - roles[CoverPathRole] = "cover_path"; - - return roles; -} void TableModel::updateRating(int rating, QModelIndex mi) { diff --git a/YACReaderLibrary/db/tablemodel.h b/YACReaderLibrary/db/tablemodel.h index 88913bc4..9df0126a 100644 --- a/YACReaderLibrary/db/tablemodel.h +++ b/YACReaderLibrary/db/tablemodel.h @@ -24,7 +24,7 @@ public: TableModel(QObject *parent = 0); TableModel( QSqlQuery &sqlquery, QObject *parent = 0); ~TableModel(); - + QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, @@ -39,8 +39,9 @@ public: //Métodos de conveniencia QStringList getPaths(const QString & _source); QString getComicPath(QModelIndex mi); + QString getCurrentPath(){return QString(_databasePath).remove("/.yacreaderlibrary");}; ComicDB getComic(const QModelIndex & mi); //--> para la edición - ComicDB getComic(int row); + //ComicDB getComic(int row); QVector getReadList(); QVector setAllComicsRead(YACReaderComicReadStatus readStatus); QList getComics(QList list); //--> recupera la información común a los comics seleccionados @@ -56,7 +57,7 @@ public: void reload(const ComicDB & comic); void resetComicRating(const QModelIndex & mi); - QHash roleNames(); + QHash roleNames() const; enum Columns { Number = 0, @@ -98,6 +99,8 @@ public slots: void finishTransaction(); void updateRating(int rating, QModelIndex mi); +protected: + private: void setupModelData( QSqlQuery &sqlquery); ComicDB _getComic(const QModelIndex & mi); @@ -110,6 +113,7 @@ private: signals: void beforeReset(); void reset(); + void isEmpty(); }; //! [0] diff --git a/YACReaderLibrary/db/treemodel.cpp b/YACReaderLibrary/db/treemodel.cpp index fcf0ada8..f04b7bef 100644 --- a/YACReaderLibrary/db/treemodel.cpp +++ b/YACReaderLibrary/db/treemodel.cpp @@ -53,6 +53,7 @@ #include "data_base_management.h" #include "folder.h" #include "db_helper.h" +#include "qnaturalsorting.h" #ifdef Q_OS_MAC #include @@ -106,7 +107,7 @@ TreeModel::TreeModel(QObject *parent) TreeModel::TreeModel( QSqlQuery &sqlquery, QObject *parent) : QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false) { - //lo más probable es que el nodo raíz no necesite tener información + //lo m�s probable es que el nodo ra�z no necesite tener informaci�n QList rootData; rootData << "root"; //id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem) rootItem = new TreeItem(rootData); @@ -265,7 +266,7 @@ void TreeModel::setupModelData(QString path) filterEnabled = false; rootItem = 0; rootBeforeFilter = 0; - //inicializar el nodo raíz + //inicializar el nodo ra�z QList rootData; rootData << "root"; //id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem) rootItem = new TreeItem(rootData); @@ -291,10 +292,10 @@ void TreeModel::setupModelData(QString path) void TreeModel::setupModelData(QSqlQuery &sqlquery, TreeItem *parent) { - //64 bits para la primary key, es decir la misma precisión que soporta sqlit 2^64 - //el diccionario permitirá encontrar cualquier nodo del árbol rápidamente, de forma que añadir un hijo a un padre sea O(1) + //64 bits para la primary key, es decir la misma precisi�n que soporta sqlit 2^64 + //el diccionario permitir� encontrar cualquier nodo del �rbol r�pidamente, de forma que a�adir un hijo a un padre sea O(1) items.clear(); - //se añade el nodo 0 + //se a�ade el nodo 0 items.insert(parent->id,parent); while (sqlquery.next()) { @@ -308,11 +309,11 @@ void TreeModel::setupModelData(QSqlQuery &sqlquery, TreeItem *parent) TreeItem * item = new TreeItem(data); item->id = record.value("id").toULongLong(); - //la inserción de hijos se hace de forma ordenada + //la inserci�n de hijos se hace de forma ordenada TreeItem * parent = items.value(record.value("parentId").toULongLong()); if(parent !=0) //TODO if parent==0 the parent of item was removed from the DB and delete on cascade didn't work, ERROR. parent->appendChild(item); - //se añade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones + //se a�ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones items.insert(item->id,item); } } @@ -323,12 +324,12 @@ void TreeModel::setupFilteredModelData() //TODO hay que liberar memoria de anteriores filtrados - //inicializar el nodo raíz + //inicializar el nodo ra�z if(rootBeforeFilter == 0) rootBeforeFilter = rootItem; else - delete rootItem;//los resultados de la búsqueda anterior deben ser borrados + delete rootItem;//los resultados de la b�squeda anterior deben ser borrados QList rootData; rootData << "root"; //id 1, padre 1, title "root" (el id, y el id del padre van a ir en la clase TreeItem) @@ -365,10 +366,10 @@ void TreeModel::setupFilteredModelData() void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent) { - //64 bits para la primary key, es decir la misma precisión que soporta sqlit 2^64 + //64 bits para la primary key, es decir la misma precisi�n que soporta sqlit 2^64 filteredItems.clear(); - //se añade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro + //se a�ade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro filteredItems.insert(parent->id,parent); while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro @@ -387,39 +388,39 @@ void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent) //id del padre quint64 parentId = record.value("parentId").toULongLong(); - //se añade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones + //se a�ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones if(!filteredItems.contains(item->id)) filteredItems.insert(item->id,item); - //es necesario conocer las coordenadas de origen para poder realizar scroll automático en la vista + //es necesario conocer las coordenadas de origen para poder realizar scroll autom�tico en la vista item->originalItem = items.value(item->id); - //si el padre ya existe en el modelo, el item se añade como hijo + //si el padre ya existe en el modelo, el item se a�ade como hijo if(filteredItems.contains(parentId)) filteredItems.value(parentId)->appendChild(item); - else//si el padre aún no se ha añadido, hay que añadirlo a él y todos los padres hasta el nodo raíz + else//si el padre a�n no se ha a�adido, hay que a�adirlo a �l y todos los padres hasta el nodo ra�z { - //comprobamos con esta variable si el último de los padres (antes del nodo raíz) ya existía en el modelo + //comprobamos con esta variable si el �ltimo de los padres (antes del nodo ra�z) ya exist�a en el modelo bool parentPreviousInserted = false; - //mientras no se alcance el nodo raíz se procesan todos los padres (de abajo a arriba) + //mientras no se alcance el nodo ra�z se procesan todos los padres (de abajo a arriba) while(parentId != ROOT ) { - //el padre no estaba en el modelo filtrado, así que se rescata del modelo original + //el padre no estaba en el modelo filtrado, as� que se rescata del modelo original TreeItem * parentItem = items.value(parentId); //se debe crear un nuevo nodo (para no compartir los hijos con el nodo original) - TreeItem * newparentItem = new TreeItem(parentItem->getData()); //padre que se añadirá a la estructura de directorios filtrados + TreeItem * newparentItem = new TreeItem(parentItem->getData()); //padre que se a�adir� a la estructura de directorios filtrados newparentItem->id = parentId; newparentItem->originalItem = parentItem; - //si el modelo contiene al padre, se añade el item actual como hijo + //si el modelo contiene al padre, se a�ade el item actual como hijo if(filteredItems.contains(parentId)) { filteredItems.value(parentId)->appendChild(item); parentPreviousInserted = true; } - //sino se registra el nodo para poder encontrarlo con posterioridad y se añade el item actual como hijo + //sino se registra el nodo para poder encontrarlo con posterioridad y se a�ade el item actual como hijo else { newparentItem->appendChild(item); @@ -432,7 +433,7 @@ void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent) parentId = parentItem->parentItem->id; } - //si el nodo es hijo de 1 y no había sido previamente insertado como hijo, se añade como tal + //si el nodo es hijo de 1 y no hab�a sido previamente insertado como hijo, se a�ade como tal if(!parentPreviousInserted) filteredItems.value(ROOT)->appendChild(item); } @@ -468,7 +469,7 @@ void TreeModel::resetFilter() //items.clear(); filteredItems.clear(); TreeItem * root = rootItem; - rootItem = rootBeforeFilter; //TODO si no se aplica el filtro previamente, esto invalidaría en modelo + rootItem = rootBeforeFilter; //TODO si no se aplica el filtro previamente, esto invalidar�a en modelo if(root !=0) delete root; @@ -518,3 +519,26 @@ void TreeModel::updateFolderFinishedStatus(const QModelIndexList &list, bool sta emit dataChanged(index(list.first().row(),TreeModel::Name),index(list.last().row(),TreeModel::Completed)); } + +QStringList TreeModel::getSubfoldersNames(const QModelIndex &mi) +{ + QStringList result; + qulonglong id = 1; + if(mi.isValid()){ + TreeItem * item = static_cast(mi.internalPointer()); + id = item->id; + } + + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + db.transaction(); + + result = DBHelper::loadSubfoldersNames(id,db); + + db.commit(); + db.close(); + QSqlDatabase::removeDatabase(_databasePath); + + //TODO sort result)) + qSort(result.begin(),result.end(),naturalSortLessThanCI); + return result; +} diff --git a/YACReaderLibrary/db/treemodel.h b/YACReaderLibrary/db/treemodel.h index 02168cbb..d36dab40 100644 --- a/YACReaderLibrary/db/treemodel.h +++ b/YACReaderLibrary/db/treemodel.h @@ -85,6 +85,8 @@ public: void updateFolderCompletedStatus(const QModelIndexList & list, bool status); void updateFolderFinishedStatus(const QModelIndexList & list, bool status); + QStringList getSubfoldersNames(const QModelIndex & mi); + enum Columns { Name = 0, Path = 1, diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index eda9d1bf..323dfcf7 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -254,6 +254,7 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db) updateComicInfo.bindValue(":notes",comicInfo->notes); bool read = comicInfo->read || comicInfo->currentPage == comicInfo->numPages.toInt(); //if current page is the las page, the comic is read(completed) + comicInfo->read = read; updateComicInfo.bindValue(":read", read?1:0); updateComicInfo.bindValue(":id", comicInfo->id); updateComicInfo.bindValue(":edited", comicInfo->edited?1:0); @@ -312,6 +313,7 @@ void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo) db.close(); QSqlDatabase::removeDatabase(libraryPath); } + //inserts qulonglong DBHelper::insert(Folder * folder, QSqlDatabase & db) { @@ -686,5 +688,18 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db) else comicInfo.existOnDb = false; - return comicInfo; + return comicInfo; +} + +QList DBHelper::loadSubfoldersNames(qulonglong folderId, QSqlDatabase &db) +{ + QList result; + QSqlQuery selectQuery(db); + selectQuery.prepare("SELECT name FROM folder WHERE parentId = :parentId AND id <> 1"); //do not select the root folder + selectQuery.bindValue(":parentId", folderId); + selectQuery.exec(); + while(selectQuery.next()){ + result << selectQuery.record().value("name").toString(); + } + return result; } diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h index a92f8fe5..146d60d5 100644 --- a/YACReaderLibrary/db_helper.h +++ b/YACReaderLibrary/db_helper.h @@ -52,6 +52,7 @@ public: static ComicDB loadComic(qulonglong id, QSqlDatabase & db); static ComicDB loadComic(QString cname, QString cpath, QString chash, QSqlDatabase & database); static ComicInfo loadComicInfo(QString hash, QSqlDatabase & db); + static QList loadSubfoldersNames(qulonglong folderId, QSqlDatabase & db); }; #endif diff --git a/YACReaderLibrary/empty_folder_widget.cpp b/YACReaderLibrary/empty_folder_widget.cpp new file mode 100644 index 00000000..b05eddd1 --- /dev/null +++ b/YACReaderLibrary/empty_folder_widget.cpp @@ -0,0 +1,89 @@ +#include "empty_folder_widget.h" + +#include +#include +#include +#include + + +#include +void testListView(QListView * l) +{ + QStringListModel * slm = new QStringListModel(QStringList() << "Lorem ipsum" << "Hailer skualer"<< "Mumbaluba X" << "Finger layden" << "Pacum tactus filer" << "Aposum" << "En" << "Lorem ipsum" << "Hailer skualer" << "Mumbaluba X" << "Finger layden" << "Pacum tactus filer" << "Aposum" << "En" ); + l->setModel(slm); +} + +EmptyFolderWidget::EmptyFolderWidget(QWidget *parent) : + QWidget(parent),subfoldersModel(new QStringListModel()) +{ + QVBoxLayout * layout = new QVBoxLayout; + + iconLabel = new QLabel(); + iconLabel->setPixmap(QPixmap(":/images/empty_folder.png")); + iconLabel->setAlignment(Qt::AlignCenter); + + titleLabel = new QLabel("Subfolders in this folder"); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); + + foldersView = new QListView(); + foldersView->setMinimumWidth(282); + foldersView->setWrapping(true); + + foldersView->setStyleSheet("QListView {background-color:transparent; border: none; color:#858585; outline:0; font-size: 18px; font:bold; show-decoration-selected: 0; margin:0}" + "QListView::item:selected {background-color: #212121; color:#CCCCCC;}" + "QListView::item:hover {background-color:#212121; color:#CCCCCC; }" + + + "QScrollBar:vertical { border: none; background: #212121; width: 14px; margin: 0 10px 0 0; }" + "QScrollBar::handle:vertical { background: #858585; width: 14px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: #212121; height: 0px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + + "QScrollBar::sub-line:vertical { border: none; background: #212121; height: 0px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" + "QScrollBar:horizontal{height:0px;}" + ); + + foldersView->setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding ); + testListView(foldersView); + + layout->addSpacing(100); + layout->addWidget(iconLabel); + layout->addSpacing(30); + layout->addWidget(titleLabel); + layout->addSpacing(12); + layout->addWidget(foldersView,1,Qt::AlignHCenter); + layout->addStretch(); + layout->setMargin(0); + layout->setSpacing(0); + + setContentsMargins(0,0,0,0); + + setStyleSheet("QWidget {background:#2A2A2A}"); + + setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding ); + setLayout(layout); + + connect(foldersView,SIGNAL(clicked(QModelIndex)),this,SLOT(onItemClicked(QModelIndex))); +} + +void EmptyFolderWidget::setSubfolders(const QModelIndex &mi, const QStringList &foldersNames) +{ + parent = mi; + subfoldersModel->setStringList(foldersNames); + foldersView->setModel(subfoldersModel); +} + +void EmptyFolderWidget::onItemClicked(const QModelIndex &mi) +{ + emit subfolderSelected(parent,mi.row()); +} + +void EmptyFolderWidget::paintEvent(QPaintEvent *) +{ + QPainter painter (this); + painter.fillRect(0,0,width(),height(),QColor("#2A2A2A")); +} diff --git a/YACReaderLibrary/empty_folder_widget.h b/YACReaderLibrary/empty_folder_widget.h new file mode 100644 index 00000000..225948be --- /dev/null +++ b/YACReaderLibrary/empty_folder_widget.h @@ -0,0 +1,32 @@ +#ifndef EMPTY_FOLDER_WIDGET_H +#define EMPTY_FOLDER_WIDGET_H + +#include +#include + +class QLabel; +class QListView; +class QStringListModel; + +class EmptyFolderWidget : public QWidget +{ + Q_OBJECT +public: + explicit EmptyFolderWidget(QWidget *parent = 0); + void setSubfolders(const QModelIndex & mi, const QStringList & foldersNames); +signals: + void subfolderSelected(QModelIndex, int); + +public slots: + void onItemClicked(const QModelIndex & mi); + +protected: + QLabel * iconLabel; + QLabel * titleLabel; + QListView * foldersView; + QModelIndex parent; + QStringListModel * subfoldersModel; + void paintEvent(QPaintEvent *); +}; + +#endif // EMPTY_FOLDER_WIDGET_H diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp new file mode 100644 index 00000000..257c2d63 --- /dev/null +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -0,0 +1,234 @@ +#include "grid_comics_view.h" + +#include +#include + +#include "QsLog.h" + +GridComicsView::GridComicsView(QWidget *parent) : + ComicsView(parent),_selectionModel(NULL) +{ + qmlRegisterType("comicModel",1,0,"TableModel"); + + view = new QQuickView(); + container = QWidget::createWindowContainer(view, this); + + container->setMinimumSize(200, 200); + container->setFocusPolicy(Qt::TabFocus); + view->setSource(QUrl("qrc:/qml/GridComicsView.qml")); + + setShowMarks(true);//TODO save this in settings + + QVBoxLayout * l = new QVBoxLayout; + l->addWidget(container); + this->setLayout(l); + + setContentsMargins(0,0,0,0); + l->setContentsMargins(0,0,0,0); + l->setSpacing(0); + + QLOG_INFO() << "GridComicsView"; +} + +GridComicsView::~GridComicsView() +{ + delete view; +} + +void GridComicsView::setToolBar(QToolBar *toolBar) +{ +QLOG_INFO() << "setToolBar"; +static_cast(this->layout())->insertWidget(1,toolBar); +} + +void GridComicsView::setModel(TableModel *model) +{ + QLOG_INFO() << "setModel"; + + QQmlContext *ctxt = view->rootContext(); + + //there is only one mothel in the system + ComicsView::setModel(model); + if(this->model != NULL) + { + QLOG_INFO() << "xxx"; + + if(_selectionModel != NULL) + delete _selectionModel; + _selectionModel = new QItemSelectionModel(this->model); + + ctxt->setContextProperty("comicsList", this->model); + ctxt->setContextProperty("comicsSelection", _selectionModel); + ctxt->setContextProperty("comicsSelectionHelper", this); + ctxt->setContextProperty("dummyValue", true); + } + +#ifdef Q_OS_MAC + ctxt->setContextProperty("backgroundColor", "#EDEDED"); + ctxt->setContextProperty("cellColor", "#FFFFFF"); + ctxt->setContextProperty("selectedColor", "#DDDDDD"); + ctxt->setContextProperty("titleColor", "#121212"); + ctxt->setContextProperty("textColor", "#636363"); + ctxt->setContextProperty("dropShadow",true); +#else + ctxt->setContextProperty("backgroundColor", "#2A2A2A"); + ctxt->setContextProperty("cellColor", "#212121"); + ctxt->setContextProperty("selectedColor", "#121212"); + ctxt->setContextProperty("titleColor", "#E6E6E6"); + ctxt->setContextProperty("textColor", "#E6E6E6"); + ctxt->setContextProperty("dropShadow",false); +#endif + + +} + +void GridComicsView::setCurrentIndex(const QModelIndex &index) +{ + QLOG_INFO() << "setCurrentIndex"; +} + +QModelIndex GridComicsView::currentIndex() +{ + QLOG_INFO() << "currentIndex"; + QModelIndexList indexes = _selectionModel->selectedRows(); + if(indexes.length()>0) + return indexes[0]; + + this->selectIndex(0); + return _selectionModel->selectedRows()[0]; +} + +QItemSelectionModel *GridComicsView::selectionModel() +{ + QLOG_INFO() << "selectionModel"; + QModelIndexList indexes = _selectionModel->selectedRows(); + if(indexes.length()==0) + this->selectIndex(0); + + return _selectionModel; +} + +void GridComicsView::scrollTo(const QModelIndex &mi, QAbstractItemView::ScrollHint hint) +{ + QLOG_INFO() << "scrollTo"; +} + +void GridComicsView::toFullScreen() +{ + QLOG_INFO() << "toFullScreen"; +} + +void GridComicsView::toNormal() +{ + QLOG_INFO() << "toNormal"; +} + +void GridComicsView::updateConfig(QSettings *settings) +{ + QLOG_INFO() << "updateConfig"; +} + +void GridComicsView::setItemActions(const QList &actions) +{ + QLOG_INFO() << "setItemActions"; +} + +void GridComicsView::setViewActions(const QList &actions) +{ + //TODO generate QML Menu from actions + QLOG_INFO() << "setViewActions"; + this->addActions(actions); + + //TODO this is completely unsafe, but QActions can't be used directly in QML + if(actions.length()>17) + { + QQmlContext *ctxt = view->rootContext(); + + ctxt->setContextProperty("openComicAction",actions[0]); + + ctxt->setContextProperty("openContainingFolderComicAction",actions[2]); + + ctxt->setContextProperty("resetComicRatingAction",actions[4]); + + ctxt->setContextProperty("editSelectedComicsAction",actions[6]); + ctxt->setContextProperty("getInfoAction",actions[7]); + ctxt->setContextProperty("asignOrderAction",actions[8]); + + ctxt->setContextProperty("selectAllComicsAction",actions[10]); + + ctxt->setContextProperty("setAsReadAction",actions[12]); + ctxt->setContextProperty("setAsNonReadAction",actions[13]); + ctxt->setContextProperty("showHideMarksAction",actions[14]); + + ctxt->setContextProperty("deleteComicsAction",actions[16]); + + ctxt->setContextProperty("toggleFullScreenAction",actions[18]); + } + else + QLOG_ERROR() << "setViewActions invoked with the wrong number of actions"; +} + +void GridComicsView::selectAll() +{ + QLOG_INFO() << "selectAll"; +} + +QSize GridComicsView::sizeHint() +{ + QLOG_INFO() << "sizeHint"; + return QSize(1280,768); +} + +//helper +void GridComicsView::selectIndex(int index) +{ + QLOG_INFO() << "selectIndex" << index; + if(_selectionModel != NULL && model!=NULL) + _selectionModel->select(model->index(index,0),QItemSelectionModel::Select | QItemSelectionModel::Rows); +} + +bool GridComicsView::isSelectedIndex(int index) +{ + if(_selectionModel != NULL && model!=NULL) + { + QModelIndex mi = model->index(index,0); + return _selectionModel->isSelected(mi); + } + return false; +} + +void GridComicsView::clear() +{ + QLOG_INFO() << "clear"; + if(_selectionModel != NULL) + { + _selectionModel->clear(); + + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("dummyValue", true); + } + //model->forceClear(); +} + +void GridComicsView::selectedItem(int index) +{ + emit doubleClicked(model->index(index,0)); +} + +void GridComicsView::setShowMarks(bool show) +{ + QLOG_INFO() << "setShowMarks"; + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("show_marks", show); +} + +void GridComicsView::closeEvent(QCloseEvent *event) +{ + QLOG_INFO() << "closeEvent"; + QObject *object = view->rootObject(); + QMetaObject::invokeMethod(object, "exit"); + container->close(); + view->close(); + event->accept(); + ComicsView::closeEvent(event); +} diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h new file mode 100644 index 00000000..3066ff68 --- /dev/null +++ b/YACReaderLibrary/grid_comics_view.h @@ -0,0 +1,59 @@ +#ifndef GRID_COMICS_VIEW_H +#define GRID_COMICS_VIEW_H + +#include "comics_view.h" + +#include + +class QAbstractListModel; +class QItemSelectionModel; +class QQuickView; +class QQuickView; + + +class GridComicsView : public ComicsView +{ + Q_OBJECT +public: + explicit GridComicsView(QWidget *parent = 0); + virtual ~GridComicsView(); + void setToolBar(QToolBar * toolBar); + void setModel(TableModel *model); + void setCurrentIndex(const QModelIndex &index); + QModelIndex currentIndex(); + QItemSelectionModel * selectionModel(); + void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ); + void toFullScreen(); + void toNormal(); + void updateConfig(QSettings * settings); + void setItemActions(const QList & actions); + void setViewActions(const QList & actions); + + QSize sizeHint(); +signals: +signals: + void comicRated(int,QModelIndex); + void doubleClicked(QModelIndex); + +public slots: + //selection helper + void selectIndex(int index); + bool isSelectedIndex(int index); + void clear(); + //double clicked item + void selectedItem(int index); + + //ComicsView + void setShowMarks(bool show); + void selectAll(); + +private: + QItemSelectionModel * _selectionModel; + QQuickView *view; + QWidget *container; + bool dummy; + void closeEvent ( QCloseEvent * event ); + +}; + +#endif // GRID_COMICS_VIEW_H diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 5f91ca7c..10c646bc 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -77,7 +77,7 @@ ../images/social_dialog/shadow.png ../images/social_dialog/twitter.png ../images/social_dialog/separator.png--> - ../images/main_toolbar/divider.png + ../images/main_toolbar/divider.png ../images/collapsed_branch_osx.png ../images/expanded_branch_osx.png ../images/folder_macosx.png @@ -100,8 +100,18 @@ ../images/comic_vine/downArrow.png ../images/comic_vine/upArrow.png ../images/find_folder.png + ../images/clear_shortcut.png + ../images/accept_shortcut.png ../images/f_overlayed.png ../images/f_overlayed_retina.png + ../images/shortcuts_group_comics.png + ../images/shortcuts_group_folders.png + ../images/shortcuts_group_general.png + ../images/shortcuts_group_libraries.png + ../images/shortcuts_group_mglass.png + ../images/shortcuts_group_page.png + ../images/shortcuts_group_reading.png + ../images/shortcuts_group_visualization.png diff --git a/YACReaderLibrary/images_osx.qrc b/YACReaderLibrary/images_osx.qrc index e400dade..64c41b0c 100644 --- a/YACReaderLibrary/images_osx.qrc +++ b/YACReaderLibrary/images_osx.qrc @@ -17,5 +17,8 @@ ../images/colapse_osx.png ../images/newLibraryIcon_osx.png ../images/openLibraryIcon_osx.png + ../images/flow_to_grid.gif + ../images/grid_to_flow.gif + ../images/empty_folder.png diff --git a/YACReaderLibrary/images_win.qrc b/YACReaderLibrary/images_win.qrc index 7b8ae9fb..ffa97d93 100644 --- a/YACReaderLibrary/images_win.qrc +++ b/YACReaderLibrary/images_win.qrc @@ -1,19 +1,23 @@ - - ../images/main_toolbar/back.png - ../images/main_toolbar/back_disabled.png - ../images/main_toolbar/forward.png - ../images/main_toolbar/forward_disabled.png - ../images/main_toolbar/settings.png - ../images/main_toolbar/server.png - ../images/main_toolbar/help.png - ../images/main_toolbar/fullscreen.png - - ../images/libraryIcon.png - ../images/setRoot.png - ../images/expand.png - ../images/colapse.png - ../images/newLibraryIcon.png - ../images/openLibraryIcon.png - + + ../images/main_toolbar/back.png + ../images/main_toolbar/back_disabled.png + ../images/main_toolbar/forward.png + ../images/main_toolbar/forward_disabled.png + ../images/main_toolbar/settings.png + ../images/main_toolbar/server.png + ../images/main_toolbar/help.png + ../images/main_toolbar/fullscreen.png + ../images/libraryIcon.png + ../images/setRoot.png + ../images/expand.png + ../images/colapse.png + ../images/newLibraryIcon.png + ../images/openLibraryIcon.png + ../images/main_toolbar/flow.png + ../images/main_toolbar/grid.png + ../images/flow_to_grid.gif + ../images/grid_to_flow.gif + ../images/empty_folder.png + diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index f2def180..b6edbc0a 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -60,6 +60,14 @@ #include "comic_vine_dialog.h" //#include "yacreader_social_dialog.h" +#include "classic_comics_view.h" +#include "grid_comics_view.h" +#include "comics_view_transition.h" +#include "empty_folder_widget.h" + +#include "edit_shortcuts_dialog.h" +#include "shortcuts_manager.h" + #include "QsLog.h" #ifdef Q_OS_WIN @@ -118,10 +126,9 @@ void LibraryWindow::setupUI() else //if(settings->value(USE_OPEN_GL).toBool() == false) showMaximized(); - if(settings->contains(COMICS_VIEW_HEADERS)) - comicView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); + /*if(settings->contains(COMICS_VIEW_HEADERS_GEOMETRY)) - comicView->horizontalHeader()->restoreGeometry(settings->value(COMICS_VIEW_HEADERS_GEOMETRY).toByteArray());*/ + comicsView->horizontalHeader()->restoreGeometry(settings->value(COMICS_VIEW_HEADERS_GEOMETRY).toByteArray());*/ /*socialDialog = new YACReaderSocialDialog(this); socialDialog->setHidden(true);*/ @@ -131,7 +138,7 @@ void LibraryWindow::doLayout() { //LAYOUT ELEMENTS------------------------------------------------------------ //--------------------------------------------------------------------------- - sVertical = new QSplitter(Qt::Vertical); //spliter derecha + QSplitter * sHorizontal = new QSplitter(Qt::Horizontal); //spliter principal #ifdef Q_OS_MAC sHorizontal->setStyleSheet("QSplitter::handle{image:none;background-color:#B8B8B8;} QSplitter::handle:vertical {height:1px;}"); @@ -142,49 +149,29 @@ void LibraryWindow::doLayout() //TOOLBARS------------------------------------------------------------------- //--------------------------------------------------------------------------- editInfoToolBar = new QToolBar(); + editInfoToolBar->setStyleSheet("QToolBar {border: none;}"); + #ifdef Q_OS_MAC libraryToolBar = addToolBar(tr("Library")); #else libraryToolBar = new YACReaderMainToolBar(this); #endif - //FLOW----------------------------------------------------------------------- - //--------------------------------------------------------------------------- - if(QGLFormat::hasOpenGL() && !settings->contains(USE_OPEN_GL)) - { - OnStartFlowSelectionDialog * flowSelDialog = new OnStartFlowSelectionDialog(); - flowSelDialog->exec(); - if(flowSelDialog->result() == QDialog::Accepted) - settings->setValue(USE_OPEN_GL,2); - else - settings->setValue(USE_OPEN_GL,0); + //FLOW----------------------------------------------------------------------- + //--------------------------------------------------------------------------- + if(QGLFormat::hasOpenGL() && !settings->contains(USE_OPEN_GL)) + { + OnStartFlowSelectionDialog * flowSelDialog = new OnStartFlowSelectionDialog(); - delete flowSelDialog; - } + flowSelDialog->exec(); + if(flowSelDialog->result() == QDialog::Accepted) + settings->setValue(USE_OPEN_GL,2); + else + settings->setValue(USE_OPEN_GL,0); - if(QGLFormat::hasOpenGL() && (settings->value(USE_OPEN_GL).toBool() == true)) - comicFlow = new ComicFlowWidgetGL(0); - else - comicFlow = new ComicFlowWidgetSW(0); - - comicFlow->updateConfig(settings); - comicFlow->setFocusPolicy(Qt::StrongFocus); - comicFlow->setShowMarks(true); - setFocusProxy(comicFlow); - - fullScreenToolTip = new QLabel(comicFlow); - fullScreenToolTip->setText(tr(" press 'F' to close fullscreen mode ")); - fullScreenToolTip->setPalette(QPalette(QColor(0,0,0))); - fullScreenToolTip->setFont(QFont("courier new",15,234)); - fullScreenToolTip->setAutoFillBackground(true); - fullScreenToolTip->hide(); - fullScreenToolTip->adjustSize(); - - comicFlow->setFocus(Qt::OtherFocusReason); - - comicFlow->addAction(toggleFullScreenAction); - comicFlow->addAction(openComicAction); + delete flowSelDialog; + } //SIDEBAR----------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -207,25 +194,32 @@ void LibraryWindow::doLayout() foldersTitle->addAction(colapseAllNodesAction); //FINAL LAYOUT------------------------------------------------------------- - sVertical->addWidget(comicFlow); - comics = new QWidget; - QVBoxLayout * comicsLayout = new QVBoxLayout; - comicsLayout->setSpacing(0); - comicsLayout->setContentsMargins(0,0,0,0); - comicsLayout->addWidget(editInfoToolBar); + comicsViewStack = new QStackedWidget(); + + if(!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow) { + comicsView = classicComicsView = new ClassicComicsView(); + comicsViewStatus = Flow; + //comicsViewStack->setCurrentIndex(Flow); + } else { + comicsView = gridComicsView = new GridComicsView(); + comicsViewStatus = Grid; + //comicsViewStack->setCurrentIndex(Grid); + } + + doComicsViewConnections(); + + comicsView->setToolBar(editInfoToolBar); + comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition()); + comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget()); + comicsViewStack->addWidget(comicsView); + + comicsViewStack->setCurrentWidget(comicsView); - editInfoToolBar->setStyleSheet("QToolBar {border: none;}"); - - comicView = new YACReaderTableView; - comicView->verticalHeader()->hide(); - comicsLayout->addWidget(comicView); - comics->setLayout(comicsLayout); - sVertical->addWidget(comics); sHorizontal->addWidget(sideBar); #ifndef Q_OS_MAC QVBoxLayout * rightLayout = new QVBoxLayout; rightLayout->addWidget(libraryToolBar); - rightLayout->addWidget(sVertical); + rightLayout->addWidget(comicsViewStack); rightLayout->setMargin(0); rightLayout->setSpacing(0); @@ -235,7 +229,7 @@ void LibraryWindow::doLayout() sHorizontal->addWidget(rightWidget); #else - sHorizontal->addWidget(sVertical); + sHorizontal->addWidget(comicsViewStack); #endif sHorizontal->setStretchFactor(0,0); @@ -257,15 +251,11 @@ void LibraryWindow::doLayout() connect(noLibrariesWidget,SIGNAL(createNewLibrary()),this,SLOT(createLibrary())); connect(noLibrariesWidget,SIGNAL(addExistingLibrary()),this,SLOT(showAddLibrary())); - comicFlow->addAction(toggleFullScreenAction); - comicFlow->addAction(openComicAction); - comicFlow->setContextMenuPolicy(Qt::ActionsContextMenu); //collapsible disabled in macosx (only temporaly) #ifdef Q_OS_MAC sHorizontal->setCollapsible(0,false); - sVertical->setCollapsible(1,false); #endif } @@ -283,6 +273,9 @@ void LibraryWindow::doDialogs() optionsDialog = new OptionsDialog(this); optionsDialog->restoreOptions(settings); + editShortcutsDialog = new EditShortcutsDialog(this); + setUpShortcutsManagement(); + #ifdef SERVER_RELEASE serverConfigDialog = new ServerConfigDialog(this); #endif @@ -302,6 +295,76 @@ void LibraryWindow::doDialogs() } +void LibraryWindow::setUpShortcutsManagement() +{ + + QList allActions; + QList tmpList; + + editShortcutsDialog->addActionsGroup("Comics",QIcon(":/images/shortcuts_group_comics.png"), + tmpList = QList() + << openComicAction + << setAsReadAction + << setAsNonReadAction + << openContainingFolderComicAction + << resetComicRatingAction + << selectAllComicsAction + << editSelectedComicsAction + << asignOrderAction + << deleteComicsAction + << getInfoAction); + + allActions << tmpList; + + editShortcutsDialog->addActionsGroup("Folders",QIcon(":/images/shortcuts_group_folders.png"), + tmpList = QList() + << setRootIndexAction + << expandAllNodesAction + << colapseAllNodesAction + << openContainingFolderAction + << setFolderAsNotCompletedAction + << setFolderAsCompletedAction + << setFolderAsReadAction + << setFolderAsUnreadAction); + allActions << tmpList; + + editShortcutsDialog->addActionsGroup("General",QIcon(":/images/shortcuts_group_general.png"), + tmpList = QList() + << backAction + << forwardAction + << helpAboutAction + << optionsAction + << serverConfigAction + << showEditShortcutsAction); + + allActions << tmpList; + + editShortcutsDialog->addActionsGroup("Libraries",QIcon(":/images/shortcuts_group_libraries.png"), + tmpList = QList() + << createLibraryAction + << openLibraryAction + << exportComicsInfoAction + << importComicsInfoAction + << exportLibraryAction + << importLibraryAction + << updateLibraryAction + << renameLibraryAction + << removeLibraryAction); + + allActions << tmpList; + + editShortcutsDialog->addActionsGroup("Visualization",QIcon(":/images/shortcuts_group_visualization.png"), + tmpList = QList() + << showHideMarksAction + << toggleFullScreenAction + << toggleComicsViewAction + << hideComicViewAction); + + allActions << tmpList; + + ShortcutsManager::getShortcutsManager().registerActions(allActions); +} + void LibraryWindow::doModels() { //folders @@ -309,7 +372,25 @@ void LibraryWindow::doModels() //comics dmCV = new TableModel(); - setFoldersFilter(""); + setFoldersFilter(""); +} + +void LibraryWindow::disconnectComicsViewConnections(ComicsView * widget) +{ + disconnect(widget, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex))); + disconnect(showHideMarksAction,SIGNAL(toggled(bool)),widget,SLOT(setShowMarks(bool))); + disconnect(widget,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); + disconnect(widget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); + disconnect(selectAllComicsAction,SIGNAL(triggered()),widget,SLOT(selectAll())); +} + +void LibraryWindow::doComicsViewConnections() +{ + connect(comicsView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex))); + connect(showHideMarksAction,SIGNAL(toggled(bool)),comicsView,SLOT(setShowMarks(bool))); + connect(comicsView,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); + connect(comicsView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); + connect(selectAllComicsAction,SIGNAL(triggered()),comicsView,SLOT(selectAll())); } void LibraryWindow::createActions() @@ -318,67 +399,90 @@ void LibraryWindow::createActions() QIcon icoBackButton; icoBackButton.addPixmap(QPixmap(":/images/main_toolbar/back.png"), QIcon::Normal); //icoBackButton.addPixmap(QPixmap(":/images/main_toolbar/back_disabled.png"), QIcon::Disabled); - backAction->setIcon(icoBackButton); + backAction->setData(BACK_ACTION_YL); + backAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(BACK_ACTION_YL)); + backAction->setIcon(icoBackButton); backAction->setDisabled(true); forwardAction = new QAction(this); QIcon icoFordwardButton; icoFordwardButton.addPixmap(QPixmap(":/images/main_toolbar/forward.png"), QIcon::Normal); //icoFordwardButton.addPixmap(QPixmap(":/images/main_toolbar/forward_disabled.png"), QIcon::Disabled); + forwardAction->setData(FORWARD_ACTION_YL); + forwardAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FORWARD_ACTION_YL)); forwardAction->setIcon(icoFordwardButton); forwardAction->setDisabled(true); createLibraryAction = new QAction(this); createLibraryAction->setToolTip(tr("Create a new library")); - createLibraryAction->setShortcut(Qt::Key_A); + createLibraryAction->setData(CREATE_LIBRARY_ACTION_YL); + createLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CREATE_LIBRARY_ACTION_YL)); createLibraryAction->setIcon(QIcon(":/images/newLibraryIcon.png")); openLibraryAction = new QAction(this); openLibraryAction->setToolTip(tr("Open an existing library")); - openLibraryAction->setShortcut(Qt::Key_O); + openLibraryAction->setData(OPEN_LIBRARY_ACTION_YL); + openLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_LIBRARY_ACTION_YL)); openLibraryAction->setIcon(QIcon(":/images/openLibraryIcon.png")); - exportComicsInfo = new QAction(tr("Export comics info"),this); - exportComicsInfo->setToolTip(tr("Export comics info")); - exportComicsInfo->setIcon(QIcon(":/images/exportComicsInfoIcon.png")); + exportComicsInfoAction = new QAction(tr("Export comics info"),this); + exportComicsInfoAction->setToolTip(tr("Export comics info")); + exportComicsInfoAction->setData(EXPORT_COMICS_INFO_ACTION_YL); + exportComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_COMICS_INFO_ACTION_YL)); + exportComicsInfoAction->setIcon(QIcon(":/images/exportComicsInfoIcon.png")); - importComicsInfo = new QAction(tr("Import comics info"),this); - importComicsInfo->setToolTip(tr("Import comics info")); - importComicsInfo->setIcon(QIcon(":/images/importComicsInfoIcon.png")); + importComicsInfoAction = new QAction(tr("Import comics info"),this); + importComicsInfoAction->setToolTip(tr("Import comics info")); + importComicsInfoAction->setData(IMPORT_COMICS_INFO_ACTION_YL); + importComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_COMICS_INFO_ACTION_YL)); + importComicsInfoAction->setIcon(QIcon(":/images/importComicsInfoIcon.png")); exportLibraryAction = new QAction(tr("Pack covers"),this); exportLibraryAction->setToolTip(tr("Pack the covers of the selected library")); + exportLibraryAction->setData(EXPORT_LIBRARY_ACTION_YL); + exportLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_LIBRARY_ACTION_YL)); exportLibraryAction->setIcon(QIcon(":/images/exportLibraryIcon.png")); importLibraryAction = new QAction(tr("Unpack covers"),this); importLibraryAction->setToolTip(tr("Unpack a catalog")); + importLibraryAction->setData(IMPORT_LIBRARY_ACTION_YL); + importLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_LIBRARY_ACTION_YL)); importLibraryAction->setIcon(QIcon(":/images/importLibraryIcon.png")); updateLibraryAction = new QAction(tr("Update library"),this); updateLibraryAction->setToolTip(tr("Update current library")); - updateLibraryAction->setShortcut(Qt::Key_U); + updateLibraryAction->setData(UPDATE_LIBRARY_ACTION_YL); + updateLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_LIBRARY_ACTION_YL)); updateLibraryAction->setIcon(QIcon(":/images/updateLibraryIcon.png")); renameLibraryAction = new QAction(tr("Rename library"),this); renameLibraryAction->setToolTip(tr("Rename current library")); - renameLibraryAction->setShortcut(Qt::Key_R); + renameLibraryAction->setData(RENAME_LIBRARY_ACTION_YL); + renameLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIBRARY_ACTION_YL)); renameLibraryAction->setIcon(QIcon(":/images/editIcon.png")); removeLibraryAction = new QAction(tr("Remove library"),this); removeLibraryAction->setToolTip(tr("Remove current library from your collection")); + removeLibraryAction->setData(REMOVE_LIBRARY_ACTION_YL); + removeLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_LIBRARY_ACTION_YL)); removeLibraryAction->setIcon(QIcon(":/images/removeLibraryIcon.png")); openComicAction = new QAction(tr("Open current comic"),this); openComicAction->setToolTip(tr("Open current comic on YACReader")); - openComicAction->setShortcut(Qt::Key_Return); + openComicAction->setData(OPEN_COMIC_ACTION_YL); + openComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_COMIC_ACTION_YL)); openComicAction->setIcon(QIcon(":/images/openInYACReader.png")); setAsReadAction = new QAction(tr("Set as read"),this); setAsReadAction->setToolTip(tr("Set comic as read")); + setAsReadAction->setData(SET_AS_READ_ACTION_YL); + setAsReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_READ_ACTION_YL)); setAsReadAction->setIcon(QIcon(":/images/setReadButton.png")); setAsNonReadAction = new QAction(tr("Set as unread"),this); setAsNonReadAction->setToolTip(tr("Set comic as unread")); + setAsNonReadAction->setData(SET_AS_NON_READ_ACTION_YL); + setAsNonReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NON_READ_ACTION_YL)); setAsNonReadAction->setIcon(QIcon(":/images/setUnread.png")); /*setAllAsReadAction = new QAction(tr("Set all as read"),this); @@ -391,115 +495,166 @@ void LibraryWindow::createActions() showHideMarksAction = new QAction(tr("Show/Hide marks"),this); showHideMarksAction->setToolTip(tr("Show or hide readed marks")); - showHideMarksAction->setShortcut(Qt::Key_M); + showHideMarksAction->setData(SHOW_HIDE_MARKS_ACTION_YL); + showHideMarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_MARKS_ACTION_YL)); showHideMarksAction->setCheckable(true); showHideMarksAction->setIcon(QIcon(":/images/showMarks.png")); showHideMarksAction->setChecked(true); toggleFullScreenAction = new QAction(tr("Fullscreen mode on/off"),this); - toggleFullScreenAction->setToolTip(tr("Fullscreen mode on/off (F)")); - toggleFullScreenAction->setShortcut(Qt::Key_F); + toggleFullScreenAction->setToolTip(tr("Fullscreen mode on/off")); + toggleFullScreenAction->setData(TOGGLE_FULL_SCREEN_ACTION_YL); + toggleFullScreenAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_FULL_SCREEN_ACTION_YL)); QIcon icoFullscreenButton; icoFullscreenButton.addPixmap(QPixmap(":/images/main_toolbar/fullscreen.png"), QIcon::Normal); toggleFullScreenAction->setIcon(icoFullscreenButton); helpAboutAction = new QAction(this); helpAboutAction->setToolTip(tr("Help, About YACReader")); - helpAboutAction->setShortcut(Qt::Key_F1); + helpAboutAction->setData(HELP_ABOUT_ACTION_YL); + helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_YL)); QIcon icoHelpButton; icoHelpButton.addPixmap(QPixmap(":/images/main_toolbar/help.png"), QIcon::Normal); helpAboutAction->setIcon(icoHelpButton); setRootIndexAction = new QAction(this); - setRootIndexAction->setShortcut(Qt::Key_0); + setRootIndexAction->setData(SET_ROOT_INDEX_ACTION_YL); + setRootIndexAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_ROOT_INDEX_ACTION_YL)); setRootIndexAction->setToolTip(tr("Select root node")); setRootIndexAction->setIcon(QIcon(":/images/setRoot.png")); expandAllNodesAction = new QAction(this); - expandAllNodesAction->setShortcut(tr("+")); expandAllNodesAction->setToolTip(tr("Expand all nodes")); + expandAllNodesAction->setData(EXPAND_ALL_NODES_ACTION_YL); + expandAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPAND_ALL_NODES_ACTION_YL)); expandAllNodesAction->setIcon(QIcon(":/images/expand.png")); colapseAllNodesAction = new QAction(this); - colapseAllNodesAction->setShortcut(tr("-")); colapseAllNodesAction->setToolTip(tr("Colapse all nodes")); + colapseAllNodesAction->setData(COLAPSE_ALL_NODES_ACTION_YL); + colapseAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(COLAPSE_ALL_NODES_ACTION_YL)); colapseAllNodesAction->setIcon(QIcon(":/images/colapse.png")); optionsAction = new QAction(this); - optionsAction->setShortcut(Qt::Key_C); optionsAction->setToolTip(tr("Show options dialog")); + optionsAction->setData(OPTIONS_ACTION_YL); + optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_YL)); QIcon icoSettingsButton; icoSettingsButton.addPixmap(QPixmap(":/images/main_toolbar/settings.png"), QIcon::Normal); optionsAction->setIcon(icoSettingsButton); serverConfigAction = new QAction(this); - serverConfigAction->setShortcut(Qt::Key_S); serverConfigAction->setToolTip(tr("Show comics server options dialog")); + serverConfigAction->setData(SERVER_CONFIG_ACTION_YL); + serverConfigAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SERVER_CONFIG_ACTION_YL)); QIcon icoServerButton; icoServerButton.addPixmap(QPixmap(":/images/main_toolbar/server.png"), QIcon::Normal); serverConfigAction->setIcon(icoServerButton); + toggleComicsViewAction = new QAction(tr("Change between comics views"),this); + toggleComicsViewAction->setToolTip(tr("Change between comics views")); + QIcon icoViewsButton; + if(!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow) + icoViewsButton.addPixmap(QPixmap(":/images/main_toolbar/grid.png"), QIcon::Normal); + else + icoViewsButton.addPixmap(QPixmap(":/images/main_toolbar/flow.png"), QIcon::Normal); + toggleComicsViewAction->setData(TOGGLE_COMICS_VIEW_ACTION_YL); + toggleComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_COMICS_VIEW_ACTION_YL)); + toggleComicsViewAction->setIcon(icoViewsButton); //socialAction = new QAction(this); openContainingFolderAction = new QAction(this); openContainingFolderAction->setText(tr("Open folder...")); + openContainingFolderAction->setData(OPEN_CONTAINING_FOLDER_ACTION_YL); + openContainingFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_ACTION_YL)); openContainingFolderAction->setIcon(QIcon(":/images/open.png")); setFolderAsNotCompletedAction = new QAction(this); setFolderAsNotCompletedAction->setText(tr("Set as uncompleted")); setFolderAsNotCompletedAction->setVisible(false); + setFolderAsNotCompletedAction->setData(SET_FOLDER_AS_NOT_COMPLETED_ACTION_YL); + setFolderAsNotCompletedAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_NOT_COMPLETED_ACTION_YL)); setFolderAsCompletedAction = new QAction(this); setFolderAsCompletedAction->setText(tr("Set as completed")); setFolderAsCompletedAction->setVisible(false); + setFolderAsCompletedAction->setData(SET_FOLDER_AS_COMPLETED_ACTION_YL); + setFolderAsCompletedAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_COMPLETED_ACTION_YL)); - setFolderAsFinishedAction = new QAction(this); - setFolderAsFinishedAction->setText(tr("Set as read")); - setFolderAsFinishedAction->setVisible(false); + setFolderAsReadAction = new QAction(this); + setFolderAsReadAction->setText(tr("Set as read")); + setFolderAsReadAction->setVisible(false); + setFolderAsReadAction->setData(SET_FOLDER_AS_READ_ACTION_YL); + setFolderAsReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_READ_ACTION_YL)); - setFolderAsNotFinishedAction = new QAction(this); - setFolderAsNotFinishedAction->setText(tr("Set as unread")); - setFolderAsNotFinishedAction->setVisible(false); + setFolderAsUnreadAction = new QAction(this); + setFolderAsUnreadAction->setText(tr("Set as unread")); + setFolderAsUnreadAction->setVisible(false); + setFolderAsUnreadAction->setData(SET_FOLDER_AS_UNREAD_ACTION_YL); + setFolderAsUnreadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_FOLDER_AS_UNREAD_ACTION_YL)); openContainingFolderComicAction = new QAction(this); openContainingFolderComicAction->setText(tr("Open containing folder...")); + openContainingFolderComicAction->setData(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL); + openContainingFolderComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL)); openContainingFolderComicAction->setIcon(QIcon(":/images/open.png")); resetComicRatingAction = new QAction(this); resetComicRatingAction->setText(tr("Reset comic rating")); + resetComicRatingAction->setData(RESET_COMIC_RATING_ACTION_YL); + resetComicRatingAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RESET_COMIC_RATING_ACTION_YL)); //Edit comics actions------------------------------------------------------ selectAllComicsAction = new QAction(this); selectAllComicsAction->setText(tr("Select all comics")); - selectAllComicsAction->setIcon(QIcon(":/images/selectAll.png")); + selectAllComicsAction->setData(SELECT_ALL_COMICS_ACTION_YL); + selectAllComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SELECT_ALL_COMICS_ACTION_YL)); + selectAllComicsAction->setIcon(QIcon(":/images/selectAll.png")); editSelectedComicsAction = new QAction(this); editSelectedComicsAction->setText(tr("Edit")); + editSelectedComicsAction->setData(EDIT_SELECTED_COMICS_ACTION_YL); + editSelectedComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EDIT_SELECTED_COMICS_ACTION_YL)); editSelectedComicsAction->setIcon(QIcon(":/images/editComic.png")); - asignOrderActions = new QAction(this); - asignOrderActions->setText(tr("Asign current order to comics")); - asignOrderActions->setIcon(QIcon(":/images/asignNumber.png")); + asignOrderAction = new QAction(this); + asignOrderAction->setText(tr("Asign current order to comics")); + asignOrderAction->setData(ASIGN_ORDER_ACTION_YL); + asignOrderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ASIGN_ORDER_ACTION_YL)); + asignOrderAction->setIcon(QIcon(":/images/asignNumber.png")); - forceConverExtractedAction = new QAction(this); - forceConverExtractedAction->setText(tr("Update cover")); - forceConverExtractedAction->setIcon(QIcon(":/images/importCover.png")); + forceCoverExtractedAction = new QAction(this); + forceCoverExtractedAction->setText(tr("Update cover")); + forceCoverExtractedAction->setData(FORCE_COVER_EXTRACTED_ACTION_YL); + forceCoverExtractedAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FORCE_COVER_EXTRACTED_ACTION_YL)); + forceCoverExtractedAction->setIcon(QIcon(":/images/importCover.png")); deleteComicsAction = new QAction(this); deleteComicsAction->setText(tr("Delete selected comics")); + deleteComicsAction->setData(DELETE_COMICS_ACTION_YL); + deleteComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DELETE_COMICS_ACTION_YL)); deleteComicsAction->setIcon(QIcon(":/images/trash.png")); - hideComicViewAction = new QAction(this); - hideComicViewAction->setText(tr("Hide comic flow")); - hideComicViewAction->setIcon(QIcon(":/images/hideComicFlow.png")); - hideComicViewAction->setCheckable(true); - hideComicViewAction->setChecked(false); + hideComicViewAction = new QAction(this); + hideComicViewAction->setText(tr("Hide comic flow")); + hideComicViewAction->setData(HIDE_COMIC_VIEW_ACTION_YL); + hideComicViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HIDE_COMIC_VIEW_ACTION_YL)); + hideComicViewAction->setIcon(QIcon(":/images/hideComicFlow.png")); + hideComicViewAction->setCheckable(true); + hideComicViewAction->setChecked(false); getInfoAction = new QAction(this); + getInfoAction->setData(GET_INFO_ACTION_YL); + getInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GET_INFO_ACTION_YL)); getInfoAction->setText(tr("Download tags from Comic Vine")); getInfoAction->setIcon(QIcon(":/images/getInfo.png")); //------------------------------------------------------------------------- + showEditShortcutsAction = new QAction(tr("Edit shortcuts"),this); + showEditShortcutsAction->setData(SHOW_EDIT_SHORTCUTS_ACTION_YL); + showEditShortcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_EDIT_SHORTCUTS_ACTION_YL)); + showEditShortcutsAction->setShortcutContext(Qt::ApplicationShortcut); + addAction(showEditShortcutsAction); //disable actions disableAllActions(); } @@ -511,7 +666,7 @@ void LibraryWindow::disableComicsActions(bool disabled) openComicAction->setDisabled(disabled); editSelectedComicsAction->setDisabled(disabled); selectAllComicsAction->setDisabled(disabled); - asignOrderActions->setDisabled(disabled); + asignOrderAction->setDisabled(disabled); setAsReadAction->setDisabled(disabled); setAsNonReadAction->setDisabled(disabled); //setAllAsReadAction->setDisabled(disabled); @@ -531,8 +686,8 @@ void LibraryWindow::disableLibrariesActions(bool disabled) updateLibraryAction->setDisabled(disabled); renameLibraryAction->setDisabled(disabled); removeLibraryAction->setDisabled(disabled); - exportComicsInfo->setDisabled(disabled); - importComicsInfo->setDisabled(disabled); + exportComicsInfoAction->setDisabled(disabled); + importComicsInfoAction->setDisabled(disabled); exportLibraryAction->setDisabled(disabled); //importLibraryAction->setDisabled(disabled); } @@ -540,8 +695,8 @@ void LibraryWindow::disableLibrariesActions(bool disabled) void LibraryWindow::disableNoUpdatedLibrariesActions(bool disabled) { updateLibraryAction->setDisabled(disabled); - exportComicsInfo->setDisabled(disabled); - importComicsInfo->setDisabled(disabled); + exportComicsInfoAction->setDisabled(disabled); + importComicsInfoAction->setDisabled(disabled); exportLibraryAction->setDisabled(disabled); } @@ -557,8 +712,8 @@ void LibraryWindow::disableFoldersActions(bool disabled) { setFolderAsNotCompletedAction->setVisible(false); setFolderAsCompletedAction->setVisible(false); - setFolderAsFinishedAction->setVisible(false); - setFolderAsNotFinishedAction->setVisible(false); + setFolderAsReadAction->setVisible(false); + setFolderAsUnreadAction->setVisible(false); } } @@ -592,6 +747,7 @@ void LibraryWindow::createToolBars() w2->setFixedWidth(10); libraryToolBar->addWidget(w2);} + libraryToolBar->addAction(toggleComicsViewAction); libraryToolBar->addAction(toggleFullScreenAction); libraryToolBar->addWidget(new QToolBarStretch()); @@ -606,6 +762,7 @@ void LibraryWindow::createToolBars() libraryToolBar->settingsButton->setDefaultAction(optionsAction); libraryToolBar->serverButton->setDefaultAction(serverConfigAction); libraryToolBar->helpButton->setDefaultAction(helpAboutAction); + libraryToolBar->toggleComicsViewButton->setDefaultAction(toggleComicsViewAction); libraryToolBar->fullscreenButton->setDefaultAction(toggleFullScreenAction); #endif @@ -614,7 +771,7 @@ void LibraryWindow::createToolBars() editInfoToolBar->addSeparator(); editInfoToolBar->addAction(editSelectedComicsAction); editInfoToolBar->addAction(getInfoAction); - editInfoToolBar->addAction(asignOrderActions); + editInfoToolBar->addAction(asignOrderAction); editInfoToolBar->addSeparator(); @@ -634,28 +791,46 @@ void LibraryWindow::createToolBars() editInfoToolBar->addAction(deleteComicsAction); editInfoToolBar->addWidget(new QToolBarStretch()); - editInfoToolBar->addAction(hideComicViewAction); - + editInfoToolBar->addAction(hideComicViewAction); } void LibraryWindow::createMenus() { - comicView->addAction(openContainingFolderComicAction); - YACReader::addSperator(comicView); + itemActions << openContainingFolderComicAction + << YACReader::createSeparator() + << resetComicRatingAction + << YACReader::createSeparator() + << editSelectedComicsAction + << getInfoAction + << asignOrderAction + << YACReader::createSeparator() + << setAsReadAction + << setAsNonReadAction + << YACReader::createSeparator() + << deleteComicsAction; - comicView->addAction(resetComicRatingAction); - YACReader::addSperator(comicView); + viewActions << openComicAction + << YACReader::createSeparator() + << openContainingFolderComicAction + << YACReader::createSeparator() + << resetComicRatingAction + << YACReader::createSeparator() + << editSelectedComicsAction + << getInfoAction + << asignOrderAction + << YACReader::createSeparator() + << selectAllComicsAction + << YACReader::createSeparator() + << setAsReadAction + << setAsNonReadAction + << showHideMarksAction + << YACReader::createSeparator() + << deleteComicsAction + << YACReader::createSeparator() + << toggleFullScreenAction; - comicView->addAction(editSelectedComicsAction); - comicView->addAction(getInfoAction); - comicView->addAction(asignOrderActions); - YACReader::addSperator(comicView); - - comicView->addAction(setAsReadAction); - comicView->addAction(setAsNonReadAction); - YACReader::addSperator(comicView); - - comicView->addAction(deleteComicsAction); + comicsView->setItemActions(itemActions); + comicsView->setViewActions(viewActions); foldersView->addAction(openContainingFolderAction); YACReader::addSperator(foldersView); @@ -664,20 +839,23 @@ void LibraryWindow::createMenus() foldersView->addAction(setFolderAsCompletedAction); YACReader::addSperator(foldersView); - foldersView->addAction(setFolderAsFinishedAction); - foldersView->addAction(setFolderAsNotFinishedAction); + foldersView->addAction(setFolderAsReadAction); + foldersView->addAction(setFolderAsUnreadAction); selectedLibrary->addAction(updateLibraryAction); selectedLibrary->addAction(renameLibraryAction); selectedLibrary->addAction(removeLibraryAction); YACReader::addSperator(selectedLibrary); - selectedLibrary->addAction(exportComicsInfo); - selectedLibrary->addAction(importComicsInfo); + selectedLibrary->addAction(exportComicsInfoAction); + selectedLibrary->addAction(importComicsInfoAction); YACReader::addSperator(selectedLibrary); selectedLibrary->addAction(exportLibraryAction); selectedLibrary->addAction(importLibraryAction); + + + //MacOSX app menus #ifdef Q_OS_MACX @@ -693,8 +871,8 @@ void LibraryWindow::createMenus() libraryMenu->addAction(removeLibraryAction); libraryMenu->addSeparator(); - libraryMenu->addAction(exportComicsInfo); - libraryMenu->addAction(importComicsInfo); + libraryMenu->addAction(exportComicsInfoAction); + libraryMenu->addAction(importComicsInfoAction); libraryMenu->addSeparator(); @@ -708,8 +886,8 @@ void LibraryWindow::createMenus() folderMenu->addAction(setFolderAsNotCompletedAction); folderMenu->addAction(setFolderAsCompletedAction); folderMenu->addSeparator(); - folderMenu->addAction(setFolderAsFinishedAction); - folderMenu->addAction(setFolderAsNotFinishedAction); + folderMenu->addAction(setFolderAsReadAction); + folderMenu->addAction(setFolderAsUnreadAction); //comic QMenu * comicMenu = new QMenu(tr("Comic")); @@ -776,10 +954,6 @@ void LibraryWindow::createConnections() connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex))); connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateHistory(QModelIndex))); - connect(comicView, SIGNAL(clicked(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex))); - connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateComicView(int))); - connect(comicView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex))); - //actions connect(createLibraryAction,SIGNAL(triggered()),this,SLOT(createLibrary())); connect(exportLibraryAction,SIGNAL(triggered()),exportLibraryDialog,SLOT(show())); @@ -791,11 +965,10 @@ void LibraryWindow::createConnections() //connect(setAllAsReadAction,SIGNAL(triggered()),this,SLOT(setComicsReaded())); //connect(setAllAsNonReadAction,SIGNAL(triggered()),this,SLOT(setComicsUnreaded())); - connect(showHideMarksAction,SIGNAL(toggled(bool)),comicFlow,SLOT(setShowMarks(bool))); - + //comicsInfoManagement - connect(exportComicsInfo,SIGNAL(triggered()),this,SLOT(showExportComicsInfo())); - connect(importComicsInfo,SIGNAL(triggered()),this,SLOT(showImportComicsInfo())); + connect(exportComicsInfoAction,SIGNAL(triggered()),this,SLOT(showExportComicsInfo())); + connect(importComicsInfoAction,SIGNAL(triggered()),this,SLOT(showImportComicsInfo())); //properties & config connect(propertiesDialog,SIGNAL(accepted()),this,SLOT(reloadCovers())); @@ -813,14 +986,14 @@ void LibraryWindow::createConnections() connect(expandAllNodesAction,SIGNAL(triggered()),foldersView,SLOT(expandAll())); connect(colapseAllNodesAction,SIGNAL(triggered()),foldersView,SLOT(collapseAll())); connect(toggleFullScreenAction,SIGNAL(triggered()),this,SLOT(toggleFullScreen())); + connect(toggleComicsViewAction,SIGNAL(triggered()),this,SLOT(toggleComicsView())); connect(optionsAction, SIGNAL(triggered()),optionsDialog,SLOT(show())); #ifdef SERVER_RELEASE connect(serverConfigAction, SIGNAL(triggered()), serverConfigDialog, SLOT(show())); #endif connect(optionsDialog, SIGNAL(optionsChanged()),this,SLOT(reloadOptions())); - //ComicFlow - connect(comicFlow,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); - connect(comicView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); + connect(optionsDialog, SIGNAL(editShortcuts()),editShortcutsDialog,SLOT(show())); + //Folders filter //connect(clearFoldersFilter,SIGNAL(clicked()),foldersFilter,SLOT(clear())); connect(foldersFilter,SIGNAL(textChanged(QString)),this,SLOT(setFoldersFilter(QString))); @@ -830,26 +1003,31 @@ void LibraryWindow::createConnections() connect(openContainingFolderComicAction,SIGNAL(triggered()),this,SLOT(openContainingFolderComic())); connect(setFolderAsNotCompletedAction,SIGNAL(triggered()),this,SLOT(setFolderAsNotCompleted())); connect(setFolderAsCompletedAction,SIGNAL(triggered()),this,SLOT(setFolderAsCompleted())); - connect(setFolderAsFinishedAction,SIGNAL(triggered()),this,SLOT(setFolderAsFinished())); - connect(setFolderAsNotFinishedAction,SIGNAL(triggered()),this,SLOT(setFolderAsNotFinished())); + connect(setFolderAsReadAction,SIGNAL(triggered()),this,SLOT(setFolderAsRead())); + connect(setFolderAsUnreadAction,SIGNAL(triggered()),this,SLOT(setFolderAsUnread())); connect(openContainingFolderAction,SIGNAL(triggered()),this,SLOT(openContainingFolder())); connect(resetComicRatingAction,SIGNAL(triggered()),this,SLOT(resetComicRating())); //connect(dm,SIGNAL(directoryLoaded(QString)),foldersView,SLOT(expandAll())); //connect(dm,SIGNAL(directoryLoaded(QString)),this,SLOT(updateFoldersView(QString))); //Comicts edition - connect(selectAllComicsAction,SIGNAL(triggered()),comicView,SLOT(selectAll())); connect(editSelectedComicsAction,SIGNAL(triggered()),this,SLOT(showProperties())); - connect(asignOrderActions,SIGNAL(triggered()),this,SLOT(asignNumbers())); + connect(asignOrderAction,SIGNAL(triggered()),this,SLOT(asignNumbers())); connect(deleteComicsAction,SIGNAL(triggered()),this,SLOT(deleteComics())); - connect(hideComicViewAction, SIGNAL(toggled(bool)),this, SLOT(hideComicFlow(bool))); + connect(hideComicViewAction, SIGNAL(toggled(bool)),this, SLOT(hideComicFlow(bool))); connect(getInfoAction,SIGNAL(triggered()),this,SLOT(showComicVineScraper())); //connect(socialAction,SIGNAL(triggered()),this,SLOT(showSocial())); + connect(comicsViewTransition,SIGNAL(transitionFinished()),this,SLOT(showComicsView())); + + connect(dmCV,SIGNAL(isEmpty()),this,SLOT(showEmptyFolderView())); + connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); + + connect(showEditShortcutsAction,SIGNAL(triggered()),editShortcutsDialog,SLOT(show())); } void LibraryWindow::loadLibrary(const QString & name) @@ -875,16 +1053,14 @@ void LibraryWindow::loadLibrary(const QString & name) 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); if(ret == QMessageBox::Yes) { - //TODO update to new version updated = DataBaseManagement::updateToCurrentVersion(path+"/library.ydb"); if(!updated) QMessageBox::critical(this,tr("Update failed"), tr("The current library can't be udpated. Check for write write permissions on: ") + path+"/library.ydb"); } else { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); disableAllActions();//TODO comprobar que se deben deshabilitar //será posible renombrar y borrar estas bibliotecas renameLibraryAction->setEnabled(true); @@ -935,9 +1111,8 @@ void LibraryWindow::loadLibrary(const QString & name) if(ret == QMessageBox::Yes) QDesktopServices::openUrl(QUrl("http://www.yacreader.com")); - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); disableAllActions();//TODO comprobar que se deben deshabilitar //será posible renombrar y borrar estas bibliotecas renameLibraryAction->setEnabled(true); @@ -946,9 +1121,8 @@ void LibraryWindow::loadLibrary(const QString & name) } else { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); disableAllActions();//TODO comprobar que se deben deshabilitar //si la librería no existe en disco, se ofrece al usuario la posibiliad de eliminarla @@ -1035,45 +1209,28 @@ void LibraryWindow::loadCovers(const QModelIndex & mi) column = mi.column(); } - //comicView->setModel(NULL); + //comicsView->setModel(NULL); dmCV->setupModelData(folderId,dm->getDatabase()); - comicView->setModel(dmCV); - comicView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); -#if QT_VERSION >= 0x050000 - comicView->horizontalHeader()->setSectionsMovable(true); -#else - comicView->horizontalHeader()->setMovable(true); -#endif - //TODO parametrizar la configuración de las columnas - for(int i = 0;ihorizontalHeader()->count();i++) - comicView->horizontalHeader()->hideSection(i); - - comicView->horizontalHeader()->showSection(0); - comicView->horizontalHeader()->showSection(1); - comicView->horizontalHeader()->showSection(2); - comicView->horizontalHeader()->showSection(3); - comicView->horizontalHeader()->showSection(7); - comicView->horizontalHeader()->showSection(8); - comicView->horizontalHeader()->showSection(10); - comicView->horizontalHeader()->showSection(11); - - - //debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles) - //así que se ecala la primera vez y después se deja el control al usuario. - //if(!settings->contains(COMICS_VIEW_HEADERS)) - comicView->resizeColumnsToContents(); - comicView->horizontalHeader()->setStretchLastSection(true); - - QStringList paths = dmCV->getPaths(currentPath()); - comicFlow->setImagePaths(paths); - comicFlow->setMarks(dmCV->getReadList()); - comicFlow->setFocus(Qt::OtherFocusReason); - + comicsView->setModel(dmCV); + QStringList paths = dmCV->getPaths(currentPath()); checkEmptyFolder(&paths); - if(paths.size()>0) - comicView->setCurrentIndex(dmCV->index(0,0)); + if(paths.size()>0) { + comicsView->setCurrentIndex(dmCV->index(0,0)); + if(comicsViewStack->currentWidget() == emptyFolderWidget) + comicsViewStack->setCurrentWidget(comicsView); + } + else + emptyFolderWidget->setSubfolders(mi,dm->getSubfoldersNames(mi)); +} + +void LibraryWindow::selectSubfolder(const QModelIndex &mi, int child) +{ + QModelIndex dest = dm->index(child,0,mi); + foldersView->setCurrentIndex(dest); + updateHistory(dest); + loadCovers(dest); } void LibraryWindow::checkEmptyFolder(QStringList * paths) @@ -1098,33 +1255,25 @@ void LibraryWindow::checkEmptyFolder(QStringList * paths) void LibraryWindow::reloadCovers() { - loadCovers(foldersView->currentIndex()); - + if(foldersView->selectionModel()->selectedRows().length()>0) + loadCovers(foldersView->currentIndex()); + else + loadCovers(QModelIndex()); +QLOG_INFO() << "reloaded covers at row : " << foldersView->currentIndex().row(); QModelIndex mi = dmCV->getIndexFromId(_comicIdEdited); - comicView->scrollTo(mi,QAbstractItemView::PositionAtCenter); - comicView->setCurrentIndex(mi); + if(mi.isValid()) + { + comicsView->scrollTo(mi,QAbstractItemView::PositionAtCenter); + comicsView->setCurrentIndex(mi); + } //centerComicFlow(mi); - comicFlow->setCenterIndex(mi.row()); -} - -void LibraryWindow::centerComicFlow(const QModelIndex & mi) -{ - comicFlow->showSlide(mi.row()); - comicFlow->setFocus(Qt::OtherFocusReason); -} - -void LibraryWindow::updateComicView(int i) -{ - QModelIndex mi = dmCV->index(i,2); - comicView->setCurrentIndex(mi); - comicView->scrollTo(mi,QAbstractItemView::EnsureVisible); } void LibraryWindow::openComic() { if(!importedCovers) { - ComicDB comic = dmCV->getComic(comicView->currentIndex()); + ComicDB comic = dmCV->getComic(comicsView->currentIndex()); QString path = currentPath(); QList siblings = dmCV->getAllComics(); @@ -1159,42 +1308,24 @@ void LibraryWindow::openComic() } } -void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) -{ - - comicFlow->setMarks(dmCV->setComicsRead(getSelectedComics(),readStatus)); - comicFlow->updateMarks(); +void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) { + dmCV->setComicsRead(getSelectedComics(),readStatus); } -void LibraryWindow::setCurrentComicReaded() -{ +void LibraryWindow::setCurrentComicReaded() { this->setCurrentComicsStatusReaded(YACReader::Read); } void LibraryWindow::setCurrentComicOpened() { - + //TODO: remove? } -void LibraryWindow::setComicsReaded() -{ - comicFlow->setMarks(dmCV->setAllComicsRead(YACReader::Read)); - comicFlow->updateMarks(); -} - -void LibraryWindow::setCurrentComicUnreaded() -{ +void LibraryWindow::setCurrentComicUnreaded() { this->setCurrentComicsStatusReaded(YACReader::Unread); } -void LibraryWindow::setComicsUnreaded() -{ - comicFlow->setMarks(dmCV->setAllComicsRead(YACReader::Unread)); - comicFlow->updateMarks(); -} - -void LibraryWindow::createLibrary() -{ +void LibraryWindow::createLibrary() { createLibraryDialog->show(libraries); } @@ -1211,8 +1342,7 @@ void LibraryWindow::create(QString source, QString dest, QString name) } -void LibraryWindow::reloadCurrentLibrary() -{ +void LibraryWindow::reloadCurrentLibrary() { loadLibrary(selectedLibrary->currentText()); } @@ -1268,24 +1398,8 @@ void LibraryWindow::loadLibraries() } -void LibraryWindow::saveLibraries() -{ - +void LibraryWindow::saveLibraries() { libraries.save(); - /*QFile f(QCoreApplication::applicationDirPath()+"/libraries.yacr"); - if(!f.open(QIODevice::WriteOnly)) - { - QMessageBox::critical(NULL,tr("Saving libraries file...."),tr("There was a problem saving YACReaderLibrary libraries file. Please, check if you have enough permissions in the YACReader root folder.")); - } - else - { - QTextStream txtS(&f); - for(QMap::iterator i = libraries.begin();i!=libraries.end();i++) - { - txtS << i.key() << "\n"; - txtS << i.value() << "\n"; - } - }*/ } void LibraryWindow::updateLibrary() @@ -1313,9 +1427,9 @@ void LibraryWindow::deleteCurrentLibrary() d.rmdir(path); if(libraries.isEmpty())//no more libraries avaliable. { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); + disableAllActions(); showNoLibrariesWidget(); } @@ -1335,9 +1449,9 @@ void LibraryWindow::removeLibrary() //selectedLibrary->setCurrentIndex(0); if(libraries.isEmpty())//no more libraries avaliable. { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); + disableAllActions(); showNoLibrariesWidget(); } @@ -1408,17 +1522,16 @@ void LibraryWindow::setRootIndex() } else { - comicView->setModel(NULL); - comicFlow->clear(); + comicsView->setModel(NULL); } - foldersView->clearSelection(); + foldersView->selectionModel()->clear(); } setFolderAsNotCompletedAction->setVisible(false); setFolderAsCompletedAction->setVisible(false); - setFolderAsFinishedAction->setVisible(false); - setFolderAsNotFinishedAction->setVisible(false); + setFolderAsReadAction->setVisible(false); + setFolderAsUnreadAction->setVisible(false); } @@ -1432,34 +1545,19 @@ void LibraryWindow::toFullScreen() { fromMaximized = this->isMaximized(); - comicFlow->hide(); - //comicFlow->setSlideSize(slideSizeF); - comicFlow->setCenterIndex(comicFlow->centerIndex()); - comics->hide(); - sideBar->hide(); + sideBar->hide(); libraryToolBar->hide(); + comicsView->toFullScreen(); + showFullScreen(); - - comicFlow->show(); - comicFlow->setFocus(Qt::OtherFocusReason); - - fullScreenToolTip->move((width()-fullScreenToolTip->width())/2,0); - fullScreenToolTip->adjustSize(); - fullScreenToolTip->show(); } void LibraryWindow::toNormal() { - fullScreenToolTip->hide(); - comicFlow->hide(); - //comicFlow->setSlideSize(slideSizeW); - comicFlow->setCenterIndex(comicFlow->centerIndex()); - comicFlow->render(); - comics->show(); sideBar->show(); - comicFlow->show(); + comicsView->toNormal(); if(fromMaximized) showMaximized(); @@ -1558,6 +1656,72 @@ void LibraryWindow::resetComicRating() dmCV->finishTransaction(); } +void LibraryWindow::switchToComicsView(ComicsView * from, ComicsView * to) +{ + disconnectComicsViewConnections(from); + from->close(); + + comicsView = to; + doComicsViewConnections(); + to->setItemActions(itemActions); + to->setViewActions(viewActions); + + comicsView->setToolBar(editInfoToolBar); + + comicsViewStack->removeWidget(from); + comicsViewStack->addWidget(comicsView); + + delete from; + + reloadCovers(); +} + +void LibraryWindow::showComicsViewTransition() +{ + comicsViewStack->setCurrentWidget(comicsViewTransition); + comicsViewTransition->startMovie(); +} + +void LibraryWindow::toggleComicsView_delayed() +{ + if(comicsViewStatus == Flow){ + QIcon icoViewsButton; + icoViewsButton.addPixmap(QPixmap(":/images/main_toolbar/flow.png"), QIcon::Normal); + toggleComicsViewAction->setIcon(icoViewsButton); + switchToComicsView(classicComicsView, gridComicsView = new GridComicsView()); + comicsViewStatus = Grid; + } + else{ + QIcon icoViewsButton; + icoViewsButton.addPixmap(QPixmap(":/images/main_toolbar/grid.png"), QIcon::Normal); + toggleComicsViewAction->setIcon(icoViewsButton); + switchToComicsView(gridComicsView, classicComicsView = new ClassicComicsView()); + comicsViewStatus = Flow; + } + + settings->setValue(COMICS_VIEW_STATUS, comicsViewStatus); +} + +void LibraryWindow::showComicsView() +{ + comicsViewStack->setCurrentWidget(comicsView); +} + +void LibraryWindow::showEmptyFolderView() +{ + comicsViewStack->setCurrentWidget(emptyFolderWidget); +} + +//TODO recover the current comics selection and restore it in the destination +void LibraryWindow::toggleComicsView() +{ + if(comicsViewStack->currentWidget()!=emptyFolderWidget) { + QTimer::singleShot(0,this,SLOT(showComicsViewTransition())); + QTimer::singleShot(32,this,SLOT(toggleComicsView_delayed())); + } else + toggleComicsView_delayed(); +} + void LibraryWindow::asignNumbers() { QModelIndexList indexList = getSelectedComics(); @@ -1580,7 +1744,7 @@ void LibraryWindow::asignNumbers() void LibraryWindow::openContainingFolderComic() { -QModelIndex modelIndex = comicView->currentIndex(); +QModelIndex modelIndex = comicsView->currentIndex(); QFileInfo file = QDir::cleanPath(currentPath() + dmCV->getComicPath(modelIndex)); #if defined Q_OS_UNIX && !defined Q_OS_MAC QString path = file.absolutePath(); @@ -1629,12 +1793,12 @@ void LibraryWindow::setFolderAsCompleted() dm->updateFolderCompletedStatus(foldersView->selectionModel()->selectedRows(),true); } -void LibraryWindow::setFolderAsFinished() +void LibraryWindow::setFolderAsRead() { dm->updateFolderFinishedStatus(foldersView->selectionModel()->selectedRows(),true); } -void LibraryWindow::setFolderAsNotFinished() +void LibraryWindow::setFolderAsUnread() { dm->updateFolderFinishedStatus(foldersView->selectionModel()->selectedRows(),false); } @@ -1656,7 +1820,7 @@ void LibraryWindow::importLibrary(QString clc,QString destPath,QString name) void LibraryWindow::reloadOptions() { //comicFlow->setFlowType(flowType); - comicFlow->updateConfig(settings); + comicsView->updateConfig(settings); } QString LibraryWindow::currentPath() @@ -1664,8 +1828,11 @@ QString LibraryWindow::currentPath() return libraries.getPath(selectedLibrary->currentText()); } +//TODO ComicsView: some actions in the comics toolbar can be relative to a certain view +//show/hide actions on show/hide widget void LibraryWindow::hideComicFlow(bool hide) { + /* if(hide) { QList sizes; @@ -1682,7 +1849,7 @@ void LibraryWindow::hideComicFlow(bool hide) sizes.append(total/3); sVertical->setSizes(sizes); } - +*/ } void LibraryWindow::showExportComicsInfo() @@ -1696,13 +1863,18 @@ void LibraryWindow::showImportComicsInfo() importComicsInfoDialog->dest = currentPath() + "/.yacreaderlibrary/library.ydb"; importComicsInfoDialog->show(); } - +#include "startup.h" +extern Startup * s; void LibraryWindow::closeEvent ( QCloseEvent * event ) { - settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry()); - settings->setValue(COMICS_VIEW_HEADERS,comicView->horizontalHeader()->saveState()); - event->accept(); - //settings->setValue(COMICS_VIEW_HEADERS_GEOMETRY,comicView->horizontalHeader()->saveGeometry()); + s->stop(); + settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry()); + + comicsView->close(); + + QApplication::instance()->processEvents(); + event->accept(); + QMainWindow::closeEvent(event); } void LibraryWindow::showNoLibrariesWidget() @@ -1751,15 +1923,16 @@ bool lessThanModelIndexRow(const QModelIndex & m1, const QModelIndex & m2) QModelIndexList LibraryWindow::getSelectedComics() { //se fuerza a que haya almenos una fila seleccionada TODO comprobar se se puede forzar a la tabla a que lo haga automáticamente - QModelIndexList selection = comicView->selectionModel()->selectedRows(); - + //avoid selection.count()==0 forcing selection in comicsView + QModelIndexList selection = comicsView->selectionModel()->selectedRows(); + QLOG_INFO() << "selection count " << selection.length(); qSort(selection.begin(),selection.end(),lessThanModelIndexRow); - if(selection.count()==0) + /*if(selection.count()==0) { - comicView->selectRow(comicFlow->centerIndex()); - selection = comicView->selectionModel()->selectedRows(); - } + comicsView->selectRow(comicFlow->centerIndex()); + selection = comicsView->selectionModel()->selectedRows(); + }*/ return selection; } @@ -1778,19 +1951,21 @@ void LibraryWindow::deleteComics() QString libraryPath = currentPath(); foreach(ComicDB comic, comics) { - paths.append(libraryPath + comic.path); + paths.append(libraryPath + comic.path); + QLOG_INFO() << comic.path; + QLOG_INFO() << comic.id; + QLOG_INFO() << comic.parentId; } ComicsRemover * remover = new ComicsRemover(indexList,paths); - //comicView->showDeleteProgress(); + //comicsView->showDeleteProgress(); dmCV->startTransaction(); - connect(remover, SIGNAL(remove(int)), dmCV, SLOT(remove(int))); - connect(remover, SIGNAL(remove(int)), comicFlow, SLOT(remove(int))); + connect(remover, SIGNAL(remove(int)), dmCV, SLOT(remove(int))); connect(remover,SIGNAL(removeError()),this,SLOT(setRemoveError())); connect(remover, SIGNAL(finished()), dmCV, SLOT(finishTransaction())); - //connect(remover, SIGNAL(finished()), comicView, SLOT(hideDeleteProgress())); + //connect(remover, SIGNAL(finished()), comicsView, SLOT(hideDeleteProgress())); connect(remover, SIGNAL(finished()),this,SLOT(checkEmptyFolder())); connect(remover, SIGNAL(finished()),this,SLOT(checkRemoveError())); connect(remover, SIGNAL(finished()), remover, SLOT(deleteLater())); @@ -1875,8 +2050,8 @@ void LibraryWindow::updateFoldersViewConextMenu(const QModelIndex &mi) bool isFinished = item->data(TreeModel::Finished).toBool(); bool isCompleted = item->data(TreeModel::Completed).toBool(); - setFolderAsFinishedAction->setVisible(!isFinished); - setFolderAsNotFinishedAction->setVisible(isFinished); + setFolderAsReadAction->setVisible(!isFinished); + setFolderAsUnreadAction->setVisible(isFinished); setFolderAsCompletedAction->setVisible(!isCompleted); setFolderAsNotCompletedAction->setVisible(isCompleted); @@ -1895,9 +2070,7 @@ void LibraryWindow::importLibraryPackage() void LibraryWindow::updateComicsView(quint64 libraryId, const ComicDB & comic) { //TODO comprobar la biblioteca.... - if(libraryId == selectedLibrary->currentIndex()) - { + if(libraryId == selectedLibrary->currentIndex()) { dmCV->reload(comic); - comicFlow->setMarks(dmCV->getReadList()); } } diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 5925d897..b7761820 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -27,7 +27,6 @@ class HelpAboutDialog; class RenameLibraryDialog; class PropertiesDialog; class PackageManager; -class ComicFlowWidget; class QCheckBox; class QPushButton; class TableModel; @@ -50,6 +49,13 @@ class YACReaderLibraryListWidget; class YACReaderTreeView; class YACReaderMainToolBar; class ComicVineDialog; +class ComicsView; +class ClassicComicsView; +class GridComicsView; +class ComicsViewTransition; +class EmptyFolderWidget; +class EditShortcutsDialog; + #include "comic_db.h" using namespace YACReader; @@ -59,7 +65,7 @@ class LibraryWindow : public QMainWindow Q_OBJECT private: YACReaderSideBar * sideBar; - QSplitter * sVertical; + CreateLibraryDialog * createLibraryDialog; ExportLibraryDialog * exportLibraryDialog; ImportLibraryDialog * importLibraryDialog; @@ -71,6 +77,7 @@ private: RenameLibraryDialog * renameLibraryDialog; PropertiesDialog * propertiesDialog; ComicVineDialog * comicVineDialog; + EditShortcutsDialog * editShortcutsDialog; //YACReaderSocialDialog * socialDialog; bool fullscreen; bool importedCovers; //if true, the library is read only (not updates,open comic or properties) @@ -80,7 +87,6 @@ private: //YACReaderSortComics * proxySort; PackageManager * packageManager; - ComicFlowWidget * comicFlow; QSize slideSizeW; QSize slideSizeF; //search filter @@ -91,15 +97,20 @@ private: QPushButton * clearFoldersFilter; QCheckBox * includeComicsCheckBox; //------------- - QWidget *comics; - YACReaderTableView * comicView; + + ComicsView * comicsView; + ClassicComicsView * classicComicsView; + GridComicsView * gridComicsView; + QStackedWidget * comicsViewStack; + ComicsViewTransition * comicsViewTransition; + EmptyFolderWidget * emptyFolderWidget; + YACReaderTreeView * foldersView; YACReaderLibraryListWidget * selectedLibrary; TreeModel * dm; TableModel * dmCV; //QStringList paths; YACReaderLibraries libraries; - QLabel * fullScreenToolTip; QStackedWidget * mainWidget; NoLibrariesWidget * noLibrariesWidget; @@ -116,8 +127,8 @@ private: QAction * createLibraryAction; QAction * openLibraryAction; - QAction * exportComicsInfo; - QAction * importComicsInfo; + QAction * exportComicsInfoAction; + QAction * importComicsInfoAction; QAction * exportLibraryAction; QAction * importLibraryAction; @@ -129,6 +140,7 @@ private: QAction * toggleFullScreenAction; QAction * optionsAction; QAction * serverConfigAction; + QAction * toggleComicsViewAction; //QAction * socialAction; //tree actions @@ -141,8 +153,8 @@ private: QAction * setFolderAsNotCompletedAction; QAction * setFolderAsCompletedAction; //-- - QAction * setFolderAsFinishedAction; - QAction * setFolderAsNotFinishedAction; + QAction * setFolderAsReadAction; + QAction * setFolderAsUnreadAction; QAction * openContainingFolderComicAction; QAction * setAsReadAction; @@ -156,11 +168,16 @@ private: //edit info actions QAction * selectAllComicsAction; QAction * editSelectedComicsAction; - QAction * asignOrderActions; - QAction * forceConverExtractedAction; + QAction * asignOrderAction; + QAction * forceCoverExtractedAction; QAction * deleteComicsAction; QAction * hideComicViewAction; + QAction *showEditShortcutsAction; + + QList itemActions; + QList viewActions; + #ifdef Q_OS_MAC QToolBar * libraryToolBar; #else @@ -191,103 +208,113 @@ private: void createConnections(); void doLayout(); void doDialogs(); + void setUpShortcutsManagement(); void doModels(); + void disconnectComicsViewConnections(ComicsView * widget); + void doComicsViewConnections(); - //ACTIONS MANAGEMENT - void disableComicsActions(bool disabled); - void disableLibrariesActions(bool disabled); - void disableNoUpdatedLibrariesActions(bool disabled); - void disableFoldersActions(bool disabled); - void disableAllActions(); - //void disableActions(); - //void enableActions(); - //void enableLibraryActions(); + //ACTIONS MANAGEMENT + void disableComicsActions(bool disabled); + void disableLibrariesActions(bool disabled); + void disableNoUpdatedLibrariesActions(bool disabled); + void disableFoldersActions(bool disabled); - QString currentPath(); + void disableAllActions(); + //void disableActions(); + //void enableActions(); + //void enableLibraryActions(); - //settings - QSettings * settings; + QString currentPath(); - //navigation backward and forward - int currentFolderNavigation; - QList history; + //settings + QSettings * settings; - bool removeError; + //navigation backward and forward + int currentFolderNavigation; + QList history; + + bool removeError; + + ComicsViewStatus comicsViewStatus; protected: - virtual void closeEvent ( QCloseEvent * event ); + virtual void closeEvent ( QCloseEvent * event ); public: - LibraryWindow(); - public slots: - void loadLibrary(const QString & path); - void loadCovers(const QModelIndex & mi); - void checkEmptyFolder(QStringList * paths = 0); - void reloadCovers(); - void centerComicFlow(const QModelIndex & mi); - void updateComicView(int i); - void openComic(); - void createLibrary(); - void create(QString source,QString dest, QString name); - void showAddLibrary(); - void openLibrary(QString path, QString name); - void loadLibraries(); - void saveLibraries(); - void reloadCurrentLibrary(); - void openLastCreated(); - void updateLibrary(); - //void deleteLibrary(); - void openContainingFolder(); - void setFolderAsNotCompleted(); - void setFolderAsCompleted(); - void setFolderAsFinished(); - void setFolderAsNotFinished(); - void openContainingFolderComic(); - void deleteCurrentLibrary(); - void removeLibrary(); - void renameLibrary(); - void rename(QString newName); - void cancelCreating(); - void stopLibraryCreator(); - void setRootIndex(); - void toggleFullScreen(); - void toNormal(); - void toFullScreen(); - void setFoldersFilter(QString filter); - void showProperties(); - void exportLibrary(QString destPath); - void importLibrary(QString clc,QString destPath,QString name); - void reloadOptions(); - void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus); - void setCurrentComicReaded(); - void setCurrentComicUnreaded(); - void setComicsReaded(); - void setComicsUnreaded(); - void hideComicFlow(bool hide); - void showExportComicsInfo(); - void showImportComicsInfo(); - void asignNumbers(); - void showNoLibrariesWidget(); - void showRootWidget(); - void showImportingWidget(); - void manageCreatingError(const QString & error); - void manageUpdatingError(const QString & error); - void manageOpeningLibraryError(const QString & error); - QModelIndexList getSelectedComics(); - void deleteComics(); - //void showSocial(); - void backward(); - void forward(); - void updateHistory(const QModelIndex & mi); - void updateFoldersViewConextMenu(const QModelIndex & mi); - void libraryAlreadyExists(const QString & name); - void importLibraryPackage(); - void updateComicsView(quint64 libraryId, const ComicDB & comic); - void setCurrentComicOpened(); - void showComicVineScraper(); - void setRemoveError(); - void checkRemoveError(); - void resetComicRating(); + LibraryWindow(); + +public slots: + void loadLibrary(const QString & path); + void loadCovers(const QModelIndex & mi); + void selectSubfolder(const QModelIndex & mi, int child); + void checkEmptyFolder(QStringList * paths = 0); + void reloadCovers(); + void openComic(); + void createLibrary(); + void create(QString source,QString dest, QString name); + void showAddLibrary(); + void openLibrary(QString path, QString name); + void loadLibraries(); + void saveLibraries(); + void reloadCurrentLibrary(); + void openLastCreated(); + void updateLibrary(); + //void deleteLibrary(); + void openContainingFolder(); + void setFolderAsNotCompleted(); + void setFolderAsCompleted(); + void setFolderAsRead(); + void setFolderAsUnread(); + void openContainingFolderComic(); + void deleteCurrentLibrary(); + void removeLibrary(); + void renameLibrary(); + void rename(QString newName); + void cancelCreating(); + void stopLibraryCreator(); + void setRootIndex(); + void toggleFullScreen(); + void toNormal(); + void toFullScreen(); + void setFoldersFilter(QString filter); + void showProperties(); + void exportLibrary(QString destPath); + void importLibrary(QString clc,QString destPath,QString name); + void reloadOptions(); + void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus); + void setCurrentComicReaded(); + void setCurrentComicUnreaded(); + void hideComicFlow(bool hide); + void showExportComicsInfo(); + void showImportComicsInfo(); + void asignNumbers(); + void showNoLibrariesWidget(); + void showRootWidget(); + void showImportingWidget(); + void manageCreatingError(const QString & error); + void manageUpdatingError(const QString & error); + void manageOpeningLibraryError(const QString & error); + QModelIndexList getSelectedComics(); + void deleteComics(); + //void showSocial(); + void backward(); + void forward(); + void updateHistory(const QModelIndex & mi); + void updateFoldersViewConextMenu(const QModelIndex & mi); + void libraryAlreadyExists(const QString & name); + void importLibraryPackage(); + void updateComicsView(quint64 libraryId, const ComicDB & comic); + void setCurrentComicOpened(); + void showComicVineScraper(); + void setRemoveError(); + void checkRemoveError(); + void resetComicRating(); + void switchToComicsView(ComicsView *from, ComicsView *to); + void showComicsViewTransition(); + void toggleComicsView_delayed();//used in orther to avoid flickering; + void showComicsView(); + void showEmptyFolderView(); + void toggleComicsView(); }; #endif diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 25f214b9..d329aa13 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -239,9 +239,12 @@ int main( int argc, char ** argv ) YACReader::exitCheck(ret); - //server shutdown + //shutdown s->stop(); delete s; + localServer->close(); + delete localServer; + delete mw; QsLogging::Logger::destroyInstance(); diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index d8b15a92..98794977 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -20,33 +20,50 @@ FlowType flowType = Strip; OptionsDialog::OptionsDialog(QWidget * parent) :YACReaderOptionsDialog(parent) { - QVBoxLayout * layout = new QVBoxLayout; + QTabWidget * tabWidget = new QTabWidget(); - QHBoxLayout * switchFlowType = new QHBoxLayout; - switchFlowType->addStretch(); - switchFlowType->addWidget(useGL); + QVBoxLayout * layout = new QVBoxLayout(this); + QVBoxLayout * flowLayout = new QVBoxLayout; + QVBoxLayout * generalLayout = new QVBoxLayout(); + QHBoxLayout * switchFlowType = new QHBoxLayout; + switchFlowType->addStretch(); + switchFlowType->addWidget(useGL); - QHBoxLayout * buttons = new QHBoxLayout(); - buttons->addStretch(); - buttons->addWidget(accept); - buttons->addWidget(cancel); + QHBoxLayout * buttons = new QHBoxLayout(); + buttons->addStretch(); + buttons->addWidget(accept); + buttons->addWidget(cancel); - layout->addWidget(sw); - layout->addWidget(gl); - layout->addLayout(switchFlowType); - layout->addLayout(buttons); + flowLayout->addWidget(sw); + flowLayout->addWidget(gl); + flowLayout->addLayout(switchFlowType); - sw->hide(); + sw->hide(); - setLayout(layout); - //restoreOptions(settings); //load options - //resize(200,0); - setModal (true); - setWindowTitle(tr("Options")); + QWidget * comicFlowW = new QWidget; + comicFlowW->setLayout(flowLayout); + + QWidget * generalW = new QWidget; + generalW->setLayout(generalLayout); + generalLayout->addWidget(shortcutsBox); + generalLayout->addStretch(); + + tabWidget->addTab(comicFlowW,tr("Comic Flow")); + tabWidget->addTab(generalW,tr("General")); + + layout->addWidget(tabWidget); + layout->addLayout(buttons); + setLayout(layout); + //restoreOptions(settings); //load options + //resize(200,0); + setModal (true); + setWindowTitle(tr("Options")); + + this->layout()->setSizeConstraint(QLayout::SetFixedSize); - this->layout()->setSizeConstraint(QLayout::SetFixedSize); } + diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc new file mode 100644 index 00000000..a02ccead --- /dev/null +++ b/YACReaderLibrary/qml.qrc @@ -0,0 +1,8 @@ + + + qml/GridComicsView.qml + qml/YACReaderScrollView.qml + qml/tick.png + qml/reading.png + + diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml new file mode 100644 index 00000000..36ee0cfb --- /dev/null +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -0,0 +1,295 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.0 +import QtQuick.Controls 1.1 +import QtGraphicalEffects 1.0 +import comicModel 1.0 + +Rectangle { + id: main + color: backgroundColor + width: parent.width + height: parent.height + anchors.margins: 0 + + function selectAll(from,to) + { + for(var i = from+1;i ci) + selectAll(ci,index); + + mouse.accepted = true; + + comicsSelectionHelper.selectIndex(index) + grid.currentIndex = index; + + } + } + + //Menu emits the 'main' signals + Menu { + id: myContextMenu + MenuItem { text: "Open comic"; enabled: true; iconSource:"qrc:///images/openInYACReader.png"; onTriggered: openComicAction.trigger() } + MenuSeparator{} + MenuItem { text: "Open containing folder..."; enabled: true; iconSource: "qrc:///images/open.png"; onTriggered: openContainingFolderComicAction.trigger() } + MenuSeparator{} + MenuItem { text: "Reset comic rating"; onTriggered: resetComicRatingAction.trigger() } + MenuSeparator{} + MenuItem { text: "Edit"; enabled: true; iconSource:"qrc:///images/editComic.png"; onTriggered: editSelectedComicsAction.trigger() } + MenuItem { text: "Download tags from Comic Vine"; enabled: true; iconSource:"qrc:///images/getInfo.png"; onTriggered: getInfoAction.trigger() } + MenuItem { text: "Asign current order to comics"; enabled: true; iconSource:"qrc:///images/asignNumber.png"; onTriggered: asignOrderAction.trigger() } + MenuSeparator{} + MenuItem { text: "Select all comics"; enabled: true; iconSource:"qrc:///images/selectAll.png"; onTriggered: selectAllComicsAction.trigger() } + MenuSeparator{} + MenuItem { text: "Set as read"; enabled: true; iconSource:"qrc:///images/setReadButton.png"; onTriggered: setAsReadAction.trigger() } + MenuItem { text: "Set as unread"; enabled: true; iconSource:"qrc:///images/setUnread.png"; onTriggered: setAsNonReadAction.trigger() } + MenuItem { text: "Show or hide read marks"; enabled: true; iconSource:"qrc:///images/showMarks.png"; onTriggered: showHideMarksAction.trigger() } + MenuSeparator{} + MenuItem { text: "Delete selected comics"; enabled: true; iconSource:"qrc:///images/trash.png"; onTriggered: deleteComicsAction.trigger() } + MenuSeparator{} + MenuItem { text: "Fullscreen mode on/off"; onTriggered: toggleFullScreenAction.trigger() } + //MenuItem { text: "Show details"; onTriggered: cell.state = 'Details'; + } + + + } + + DropShadow { + anchors.fill: source + horizontalOffset: 0 + verticalOffset: 0 + radius: 3 + samples: 24 + color: "#40000000" + transparentBorder: true; + source: realCell; + enabled: dropShadow; + visible: dropShadow; + } + + /**/ + + //cover + Image { + id: coverElement + width: 148 + height: 224 + anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 4} + source: cover_path + fillMode: Image.PreserveAspectCrop + //smooth: true + mipmap: true + //antialiasing: true + asynchronous : true + cache: false //TODO clear cache only when it is neede + } + //mark + Image { + id: mark + width: 23 + height: 23 + source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":"" + anchors {right: coverElement.right; top: coverElement.top; topMargin: 11; rightMargin: 11} + asynchronous : true + } + + //title + Text { + anchors { top: realCell.top; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 234; } + width: 148 + maximumLineCount: 2 + wrapMode: Text.WordWrap + text: title + elide: Text.ElideRight + color: titleColor + clip: true + font.letterSpacing: 0.5 + } + //number + Text { + anchors {bottom: realCell.bottom; left: realCell.left; margins: 4} + text: number?"#"+number:"" + color: textColor + font.letterSpacing: 0.5 + } + //page icon + Image { + id: pageImage + anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 5; rightMargin: 4; leftMargin: 4} + source: "page.png" + } + //numPages + Text { + id: pages + anchors {bottom: realCell.bottom; right: pageImage.left; margins: 4} + text: has_been_opened?current_page+"/"+num_pages:num_pages + color: textColor + font.letterSpacing: 0.5 + } + //rating icon + Image { + id: ratingImage + anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 5; rightMargin: Math.floor(pages.width)+12} + source: "star.png" + } + //comic rating + Text { + id: comicRating + anchors {bottom: realCell.bottom; right: ratingImage.left; margins: 4} + text: rating>0?rating:"-" + color: textColor + } + } + } + + YACReaderScrollView{ + id: scrollView + anchors.fill: parent + anchors.margins: 0 + + + GridView { + id:grid + anchors.fill: parent + cellHeight: 295 + highlight: appHighlight + focus: true + model: comicsList + delegate: appDelegate + anchors.topMargin: 20 + anchors.bottomMargin: 20 + anchors.leftMargin: 10 + anchors.rightMargin: 10 + pixelAligned: true + //flickDeceleration: -2000 + snapMode: GridView.SnapToRow + currentIndex: 0 + cacheBuffer: 0 + + + function numCellsPerRow() { + return Math.floor(width / 190); + } + + onWidthChanged: { + var numCells = numCellsPerRow(); + var rest = width % 190; + + if(numCells > 0) + { + cellWidth = Math.floor(width / numCells) ; + //console.log("numCells=",numCells,"rest=",rest,"cellWidth=",cellWidth,"width=",width); + } + } + } + focus: true + Keys.onPressed: { + if (event.modifiers & Qt.ControlModifier || event.modifiers & Qt.ShiftModifier) + return; + var numCells = grid.numCellsPerRow(); + var ci + if (event.key === Qt.Key_Right) { + ci = Math.min(grid.currentIndex+1,grid.count); + } + else if (event.key === Qt.Key_Left) { + ci = Math.max(0,grid.currentIndex-1); + } + else if (event.key === Qt.Key_Up) { + ci = Math.max(0,grid.currentIndex-numCells); + } + else if (event.key === Qt.Key_Down) { + ci = Math.min(grid.currentIndex+numCells,grid.count); + } + + event.accepted = true; + //var ci = grid.currentIndex; + grid.currentIndex = -1 + comicsSelectionHelper.clear(); + comicsSelectionHelper.selectIndex(ci); + grid.currentIndex = ci; + } + //} + + /*MouseArea { + anchors.fill: parent + onClicked: { + clicked.accepted = false; + console.log("xx"); + } + + onWheel: { + var newValue = Math.max(0,scrollView.flickableItem.contentY - wheel.angleDelta.y) + scrollView.flickableItem.contentY = newValue + + } + }*/ + /*ScrollBar { + flickable: grid; + } + + PerformanceMeter { + anchors {top: parent.top; left: parent.left; margins: 4} + id: performanceMeter + width: 128 + height: 64 + enabled: (dummyValue || !dummyValue) + }*/ + } +} + + diff --git a/YACReaderLibrary/qml/YACReaderScrollView.qml b/YACReaderLibrary/qml/YACReaderScrollView.qml new file mode 100644 index 00000000..a8dc57ad --- /dev/null +++ b/YACReaderLibrary/qml/YACReaderScrollView.qml @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 +import QtQuick.Controls.Styles 1.1 + +/*! + \qmltype ScrollView + \inqmlmodule QtQuick.Controls + \since 5.1 + \ingroup views + \brief Provides a scrolling view within another Item. + + A ScrollView can be used either to replace a \l Flickable or decorate an + existing \l Flickable. Depending on the platform, it will add scroll bars and + a content frame. + + Only one Item can be a direct child of the ScrollView and the child is implicitly anchored + to fill the scroll view. + + Example: + \code + ScrollView { + Image { source: "largeImage.png" } + } + \endcode + + In the previous example the Image item will implicitly get scroll behavior as if it was + used within a \l Flickable. The width and height of the child item will be used to + define the size of the content area. + + Example: + \code + ScrollView { + ListView { + ... + } + } + \endcode + + In this case the content size of the ScrollView will simply mirror that of its contained + \l flickableItem. + + You can create a custom appearance for a ScrollView by + assigning a \l {QtQuick.Controls.Styles::ScrollViewStyle}{ScrollViewStyle}. +*/ + +FocusScope { + id: root + + implicitWidth: 240 + implicitHeight: 150 + + /*! + This property tells the ScrollView if it should render + a frame around its content. + + The default value is \c false. + */ + property bool frameVisible: false + + /*! + This property controls if there should be a highlight + around the frame when the ScrollView has input focus. + + The default value is \c false. + + \note This property is only applicable on some platforms, such + as Mac OS. + */ + property bool highlightOnFocus: false + + /*! + \qmlproperty Item ScrollView::viewport + + The viewport determines the current "window" on the contentItem. + In other words, it clips it and the size of the viewport tells you + how much of the content area is visible. + */ + property alias viewport: viewportItem + + /*! + \qmlproperty Item ScrollView::flickableItem + + The flickableItem of the ScrollView. If the contentItem provided + to the ScrollView is a Flickable, it will be the \l contentItem. + */ + readonly property alias flickableItem: internal.flickableItem + + /*! + The contentItem of the ScrollView. This is set by the user. + + Note that the definition of contentItem is somewhat different to that + of a Flickable, where the contentItem is implicitly created. + */ + default property Item contentItem + + /*! \internal */ + property Item __scroller: scroller + /*! \internal */ + property alias __wheelAreaScrollSpeed: wheelArea.scrollSpeed + /*! \internal */ + property int __scrollBarTopMargin: 0 + /*! \internal */ + property int __viewTopMargin: 0 + /*! \internal */ + property alias __horizontalScrollBar: scroller.horizontalScrollBar + /*! \internal */ + property alias __verticalScrollBar: scroller.verticalScrollBar + /*! \qmlproperty Component ScrollView::style + + The style Component for this control. + \sa {Qt Quick Controls Styles QML Types} + + */ + property Component style: Qt.createComponent(Settings.style + "/ScrollViewStyle.qml", root) + + /*! \internal */ + property Style __style: styleLoader.item + + activeFocusOnTab: true + + onContentItemChanged: { +//console.log("onContentItemChanged"); + if (contentItem.hasOwnProperty("contentY") && // Check if flickable + contentItem.hasOwnProperty("contentHeight")) { + internal.flickableItem = contentItem // "Use content if it is a flickable + internal.flickableItem.parent = viewportItem + } else { + internal.flickableItem = flickableComponent.createObject(viewportItem) + contentItem.parent = internal.flickableItem.contentItem + } + internal.flickableItem.anchors.fill = viewportItem + if (!Settings.hasTouchScreen) + internal.flickableItem.interactive = false + } + + + children: Item { + id: internal + + property Flickable flickableItem + + Loader { + id: styleLoader + sourceComponent: style + onStatusChanged: { + if (status === Loader.Error) + console.error("Failed to load Style for", root) + } + property alias __control: root + } + + Binding { + target: flickableItem + property: "contentHeight" + when: contentItem !== flickableItem + value: contentItem ? contentItem.height : 0 + } + + Binding { + target: flickableItem + when: contentItem !== flickableItem + property: "contentWidth" + value: contentItem ? contentItem.width : 0 + } + + Connections { + target: flickableItem + + onContentYChanged: { + //console.log("onContentYChanged2"); + scroller.blockUpdates = true + scroller.verticalScrollBar.value = flickableItem.contentY + scroller.blockUpdates = false + } + + onContentXChanged: { + //console.log("onContentXChanged2"); + scroller.blockUpdates = true + scroller.horizontalScrollBar.value = flickableItem.contentX + scroller.blockUpdates = false + } + + } + + anchors.fill: parent + + Component { + id: flickableComponent + Flickable {} + } + + WheelArea { + id: wheelArea + parent: flickableItem + + // ### Note this is needed due to broken mousewheel behavior in Flickable. + + anchors.fill: parent + + property int stepSize: 295 + + property int acceleration: 40 + property int flickThreshold: Settings.dragThreshold + property real speedThreshold: 3 + property real ignored: 0.001 // ## flick() does not work with 0 yVelocity + property int maxFlick: 400 + + property bool horizontalRecursionGuard: false + property bool verticalRecursionGuard: false + + horizontalMinimumValue: flickableItem ? flickableItem.originX : 0 + horizontalMaximumValue: flickableItem ? flickableItem.originX + flickableItem.contentWidth - viewport.width : 0 + + verticalMinimumValue: flickableItem ? flickableItem.originY : 0 + verticalMaximumValue: flickableItem ? flickableItem.originY + flickableItem.contentHeight - viewport.height + __viewTopMargin : 0 + + Connections { + target: flickableItem + + onContentYChanged: { + //console.log("onContentYChanged"); + wheelArea.verticalRecursionGuard = true + wheelArea.verticalValue = flickableItem.contentY + wheelArea.verticalRecursionGuard = false + } + onContentXChanged: { + //console.log("onContentXChanged"); + wheelArea.horizontalRecursionGuard = true + wheelArea.horizontalValue = flickableItem.contentX + wheelArea.horizontalRecursionGuard = false + } + } + + onVerticalValueChanged: { + if (!verticalRecursionGuard) { + //console.log(verticalDelta); + + if (flickableItem.contentY < flickThreshold && verticalDelta > speedThreshold) { + flickableItem.flick(ignored, Math.min(maxFlick, acceleration * verticalDelta)) + } else if (flickableItem.contentY > flickableItem.contentHeight + - flickThreshold - viewport.height && verticalDelta < -speedThreshold) { + flickableItem.flick(ignored, Math.max(-maxFlick, acceleration * verticalDelta)) + } else { + var absDelta = Math.abs(verticalDelta); + + if(verticalDelta < 0) + flickableItem.contentY = verticalValue + Math.min(98,0.93*absDelta+4.5); + else + flickableItem.contentY = verticalValue - Math.min(98,0.93*absDelta+4.5); +} + + + //TODO: snap to row + + } + + } + + onHorizontalValueChanged: { + if (!horizontalRecursionGuard) + flickableItem.contentX = horizontalValue + } + } + + ScrollViewHelper { + id: scroller + anchors.fill: parent + active: wheelArea.active + property bool outerFrame: !frameVisible || !(__style ? __style.__externalScrollBars : 0) + property int scrollBarSpacing: outerFrame ? 0 : (__style ? __style.__scrollBarSpacing : 0) + property int verticalScrollbarOffset: verticalScrollBar.visible && !verticalScrollBar.isTransient ? + verticalScrollBar.width + scrollBarSpacing : 0 + property int horizontalScrollbarOffset: horizontalScrollBar.visible && !horizontalScrollBar.isTransient ? + horizontalScrollBar.height + scrollBarSpacing : 0 + Loader { + id: frameLoader + sourceComponent: __style ? __style.frame : null + anchors.fill: parent + anchors.rightMargin: scroller.outerFrame ? 0 : scroller.verticalScrollbarOffset + anchors.bottomMargin: scroller.outerFrame ? 0 : scroller.horizontalScrollbarOffset + } + + Item { + id: viewportItem + anchors.fill: frameLoader + anchors.topMargin: frameVisible ? __style.padding.top : 0 + anchors.leftMargin: frameVisible ? __style.padding.left : 0 + anchors.rightMargin: (frameVisible ? __style.padding.right : 0) + (scroller.outerFrame ? scroller.verticalScrollbarOffset : 0) + anchors.bottomMargin: (frameVisible ? __style.padding.bottom : 0) + (scroller.outerFrame ? scroller.horizontalScrollbarOffset : 0) + clip: true + } + } + FocusFrame { visible: highlightOnFocus && root.activeFocus } + } +} diff --git a/YACReaderLibrary/qml/page-macosx.png b/YACReaderLibrary/qml/page-macosx.png new file mode 100644 index 0000000000000000000000000000000000000000..c8216591679ffb2e0dac358288275c4ce8d539ce GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MZTUcjv*Ddl6d&}|DSK*6bfGxv60~nlO_Wbn*`g(g%*rQ z(i0ExF*Q~=y12A3>9M|ESYq48wBT-!f!T$Y|2{k{46-5{4#+fnGdeUdGC1cdp31NN R!3#8)!PC{xWt~$(697>)GP3{x literal 0 HcmV?d00001 diff --git a/YACReaderLibrary/qml/page.png b/YACReaderLibrary/qml/page.png new file mode 100644 index 0000000000000000000000000000000000000000..100db8a07ce55af57e69d58fd70c3ec37690e1ed GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MYf(Ujv*Ddl795dN*Ekq=s4cMvViLzb0Jg5`9lq|Doh`1 z7AP^gO(=3xIFPEejA53HFf*eAJF8BM43|IxgRqEQ=BZ0eSwMprJYD@<);T3K0RU%2 BE8+kE literal 0 HcmV?d00001 diff --git a/YACReaderLibrary/qml/reading.png b/YACReaderLibrary/qml/reading.png new file mode 100644 index 0000000000000000000000000000000000000000..a26a81d63a321ff8c73407b041c96b3c22c3576b GIT binary patch literal 374 zcmV-+0g3*JP)+7*9lVSQEwMA4ff7z&p)DoQSkRc@A2T3PiBWd_$!B1)`!d-qGqS2G(IqLR zi?D!Q_7E=NlpSM#+PVK79MCDk2DZd!6>tE~=_4HA6@n+eR|M9f6Amy{I~Ttz0WYXO z)KkTMz@#~I9&kQmPw0`yyr%Mv(5pL7@pZE_!!6<3cmIAa4Ep2b$qQ(_6UFN1DJC24IAC14hUQ z{YySGLN_QQFan?XWQ4LoH)uNnY>?WLi7H4=I{CQR_rj!rre}xA-v7M^7fDX>;cf~LG0Dm%$F|N521bkdXAUS~WA?lm?MZ7#7tIvulm>39y z^0RoR(IeYhR2qTw+usVKMhmq=u>Go$FUqaTSFcB63jr5@3tQ!@qV0MlUxilrY|T!@ m`KRr){7>jM>~=Ii0R{k?6iGx9CTxW#|uyQ7I> zD^q~9RKpKj0d0quY%6v!>}vZQ@Vw#0R|gpeQT~Qc4?n%w_NLv7E1~dU<%&HFX6onI zXZEPEZOXLUBq2O&U$?^_##IrFTHhG8`hq9h2yi<%^NLk51r*Mi#nT`mV$R+eA?Ri8 naI}!EnyIhB!$FLh!+>GZiKSU*Paew!x{txr)z4*}Q$iB}nx9l& literal 0 HcmV?d00001 diff --git a/YACReaderLibrary/qml/tick.png b/YACReaderLibrary/qml/tick.png new file mode 100644 index 0000000000000000000000000000000000000000..78a20644c27b468c50767aa4a44597662f7253de GIT binary patch literal 488 zcmVP)wXM;%Yz~3&g? zC_;UD5u4#56c~&gN1%AQ2I4Rwg|QO@b$}DpJhgt^2k28-cbAj1Q&xen-6dqYD*IeUA1 zMJ6Vu&map(Fc<__K{>P+nl>?9e*E}xKTw#0_9*{be eYPCN=fB^su{-6g#-^-l<0000 + + qml/page-macosx.png + qml/star-macosx.png + + diff --git a/YACReaderLibrary/qml_win.qrc b/YACReaderLibrary/qml_win.qrc new file mode 100644 index 00000000..59e2872f --- /dev/null +++ b/YACReaderLibrary/qml_win.qrc @@ -0,0 +1,6 @@ + + + qml/page.png + qml/star.png + + diff --git a/YACReaderLibrary/server/startup.cpp b/YACReaderLibrary/server/startup.cpp index cb1f444f..7166e402 100644 --- a/YACReaderLibrary/server/startup.cpp +++ b/YACReaderLibrary/server/startup.cpp @@ -37,7 +37,7 @@ void Startup::start() { //QSettings* debugLogSettings=new QSettings(configFileName,QSettings::IniFormat,app); //debugLogSettings->beginGroup("debugLogFile"); Logger* logger=new FileLogger(mainLogSettings,10000,app); - logger->installMsgHandler(); + logger->installMsgHandler(); // Configure template loader and cache QSettings* templateSettings=new QSettings(configFileName,QSettings::IniFormat,app); @@ -65,9 +65,14 @@ void Startup::start() { void Startup::stop() { - qDebug("ServiceHelper: Service has been stopped"); - // QCoreApplication destroys all objects that have been created in start(). - delete listener; + qDebug("ServiceHelper: Service has been stopped"); + // QCoreApplication destroys all objects that have been created in start(). + if(listener!=nullptr) + { + listener->close(); + delete listener; + listener = nullptr; + } } diff --git a/YACReaderLibrary/yacreader_local_server.cpp b/YACReaderLibrary/yacreader_local_server.cpp index a24c184f..8d6d7c82 100644 --- a/YACReaderLibrary/yacreader_local_server.cpp +++ b/YACReaderLibrary/yacreader_local_server.cpp @@ -64,7 +64,12 @@ bool YACReaderLocalServer::isRunning() socket.connectToServer(YACREADERLIBRARY_GUID); if (socket.waitForConnected(500)) return true; // Server is running (another instance of YACReaderLibrary has been launched) - return false; + return false; +} + +void YACReaderLocalServer::close() +{ + localServer->close(); } diff --git a/YACReaderLibrary/yacreader_local_server.h b/YACReaderLibrary/yacreader_local_server.h index d6c8832b..d5432e60 100644 --- a/YACReaderLibrary/yacreader_local_server.h +++ b/YACReaderLibrary/yacreader_local_server.h @@ -21,6 +21,7 @@ public slots: bool isListening(); void sendResponse(); static bool isRunning(); + void close(); private: //void run(); QLocalServer * localServer; diff --git a/YACReaderLibrary/yacreader_main_toolbar.cpp b/YACReaderLibrary/yacreader_main_toolbar.cpp index 61f6a3da..c4e1dc82 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.cpp +++ b/YACReaderLibrary/yacreader_main_toolbar.cpp @@ -44,11 +44,14 @@ YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) : helpButton->setStyleSheet(qToolButtonStyleSheet); helpButton->setIconSize(QSize(14,25)); + toggleComicsViewButton = new QToolButton; + toggleComicsViewButton->setStyleSheet(qToolButtonStyleSheet); + toggleComicsViewButton->setIconSize(QSize(24,24)); + fullscreenButton = new QToolButton(); fullscreenButton->setStyleSheet(qToolButtonStyleSheet); fullscreenButton->setIconSize(QSize(24,24)); - mainLayout->setMargin(0); mainLayout->setSpacing(0); @@ -66,6 +69,8 @@ YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) : mainLayout->addStretch(); + mainLayout->addWidget(toggleComicsViewButton); + addWideDivider(); mainLayout->addWidget(fullscreenButton); mainLayout->addSpacing(10); diff --git a/YACReaderLibrary/yacreader_main_toolbar.h b/YACReaderLibrary/yacreader_main_toolbar.h index b45dbf4d..a21fd3f5 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.h +++ b/YACReaderLibrary/yacreader_main_toolbar.h @@ -9,6 +9,7 @@ class QResizeEvent; class QPaintEvent; class QHBoxLayout; +//TODO create methods for adding actions, separators and sctreches dynimically class YACReaderMainToolBar : public QWidget { Q_OBJECT @@ -21,8 +22,10 @@ public: QToolButton * settingsButton; QToolButton * serverButton; QToolButton * helpButton; + QToolButton * toggleComicsViewButton; QToolButton * fullscreenButton; + void setCurrentFolderName(const QString & name); signals: diff --git a/common/yacreader_flow_gl.cpp b/common/yacreader_flow_gl.cpp index 58588251..5ce9e1dc 100644 --- a/common/yacreader_flow_gl.cpp +++ b/common/yacreader_flow_gl.cpp @@ -1059,7 +1059,7 @@ void YACReaderFlowGL::keyPressEvent(QKeyEvent *event) if(event->key() == Qt::Key_Up) { - emit selected(centerIndex()); + //emit selected(centerIndex()); return; } diff --git a/common/yacreader_global.cpp b/common/yacreader_global.cpp index 0ac9c43e..c8ad06c3 100644 --- a/common/yacreader_global.cpp +++ b/common/yacreader_global.cpp @@ -19,3 +19,11 @@ void YACReader::addSperator(QWidget *w) separator->setSeparator(true); w->addAction(separator); } + + +QAction * YACReader::createSeparator() +{ + QAction * a = new QAction(0); + a->setSeparator(true); + return a; +} diff --git a/common/yacreader_global.h b/common/yacreader_global.h index d60fa7b5..c8758ca3 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -55,6 +55,7 @@ #define MAIN_WINDOW_STATE "MAIN_WINDOW_STATE" #define COMICS_VIEW_HEADERS "COMICS_VIEW_HEADERS" #define COMICS_VIEW_HEADERS_GEOMETRY "COMICS_VIEW_HEADERS_GEOMETRY" +#define COMICS_VIEW_STATUS "COMICS_VIEW_STATUS" #define NUM_DAYS_BETWEEN_VERSION_CHECKS "NUM_DAYS_BETWEEN_VERSION_CHECKS" #define LAST_VERSION_CHECK "LAST_VERSION_CHECK" @@ -94,8 +95,15 @@ namespace YACReader SevenZNotFound = 700 }; + enum ComicsViewStatus + { + Flow, + Grid + }; + QString getSettingsPath(); void addSperator(QWidget * w); +QAction * createSeparator(); } #endif diff --git a/custom_widgets/yacreader_options_dialog.cpp b/custom_widgets/yacreader_options_dialog.cpp index f9fcae64..c89b44dc 100644 --- a/custom_widgets/yacreader_options_dialog.cpp +++ b/custom_widgets/yacreader_options_dialog.cpp @@ -10,6 +10,7 @@ #include #include #include +#include YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget * parent) :QDialog(parent) @@ -23,6 +24,16 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget * parent) cancel->setDefault(true); + + QVBoxLayout * shortcutsLayout = new QVBoxLayout(); + QPushButton * shortcutsButton = new QPushButton(tr("Edit shortcuts")); + shortcutsLayout->addWidget(shortcutsButton); + + shortcutsBox = new QGroupBox(tr("Shortcuts")); + shortcutsBox->setLayout(shortcutsLayout); + + connect(shortcutsButton,SIGNAL(clicked()),this,SIGNAL(editShortcuts())); + connect(accept,SIGNAL(clicked()),this,SLOT(saveOptions())); connect(cancel,SIGNAL(clicked()),this,SLOT(restoreOptions())); //TODO fix this connect(cancel,SIGNAL(clicked()),this,SLOT(close())); diff --git a/custom_widgets/yacreader_options_dialog.h b/custom_widgets/yacreader_options_dialog.h index 67a08230..9b347ae8 100644 --- a/custom_widgets/yacreader_options_dialog.h +++ b/custom_widgets/yacreader_options_dialog.h @@ -8,6 +8,7 @@ class YACReaderGLFlowConfigWidget; class QCheckBox; class QPushButton; class QSettings; +class QGroupBox; class YACReaderOptionsDialog : public QDialog { @@ -20,6 +21,8 @@ protected: QPushButton * accept; QPushButton * cancel; + QGroupBox * shortcutsBox; + QSettings * settings; QSettings * previousSettings; @@ -56,6 +59,7 @@ protected slots: signals: void optionsChanged(); + void editShortcuts(); }; -#endif // YACREADER_OPTIONS_DIALOG_H \ No newline at end of file +#endif // YACREADER_OPTIONS_DIALOG_H diff --git a/custom_widgets/yacreader_search_line_edit.cpp b/custom_widgets/yacreader_search_line_edit.cpp index 11f42622..26d00c31 100644 --- a/custom_widgets/yacreader_search_line_edit.cpp +++ b/custom_widgets/yacreader_search_line_edit.cpp @@ -34,7 +34,7 @@ YACReaderSearchLineEdit::YACReaderSearchLineEdit(QWidget *parent) qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2)); #ifdef Q_OS_MAC - setMaximumWidth(300); + setMaximumWidth(212); #endif } diff --git a/images/accept_shortcut.png b/images/accept_shortcut.png new file mode 100644 index 0000000000000000000000000000000000000000..dc0017b95566704bdcb79d41406bb660df56f9ea GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^{2}1{rUgjo_S|OXCsqC{Mo;?wR|a=Y*{`GLBA8( z3?{B9v=dMl6BCtnxY+YXhDl0%fra#{Li-TGK&gkb7M}B9(R4CnnC~W#;NqupqHCd( yg=tcTn{fl}1{rUgjo_S{j>+FR3_;{%avpQ9##6^Uda62oW zNGrK>{q}EpdHFWU#B*%7+_wB~T$jLdu_xrSvDp4a%pv=QADhQ~^09FGZEq$eYhW0_ v(6%D2%SqZcce$`f=F1Z@T|p8K4U7!guUGzRnj~lew3Wfr)z4*}Q$iB}vI|AZ literal 0 HcmV?d00001 diff --git a/images/empty_folder.png b/images/empty_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..fa3b13cde0239492769d94f53bf767b651edaf75 GIT binary patch literal 2515 zcmb7GdpHwp8{dYQr1FxIOnFCAbdW>FBw7wjuM%N1iX37QIgFtb5#C;Eyg8&^Bp*VW z(+oL_Eklbk?~p^W18uXDZ{PR*^BvynyRQEE-Ov4duHWyz@9X~KdG4P(i`b&9r3?T7 zwm6=#cLM-`aM^iPX_E}uqU}^!*cIjA8Fd~T7!~6e82~tW1?wN6>lo&DHNY*v?@C-m ze*g>s07pC8pS%z|@$EC&Yxl=p?SB1db5v0sPN?SC8o(wo)N$oC{RB4 z^0R7_Gcl5ImaAcJcpf@`3<3VCa2qo$emKRCTf?v*;Ov`830DJ6X{?66AkztF-+Sw| zPd2zqeACO1bq2-XZ^XOIuda6nmV6a%>0Lnzj}DhiuHK9~-G%*K2XbDi+)R8cFl0*`pO}v^NWfk@fyP+uRFO9L7;l81 zr#|YJDPHsiOZ}9Wvx;x;R`-+^O{$pAIV!@qiw6m2nhFnmAiwIvnkgp5?c#c*Lk0MH zlaF*L@Tq%_@07u6D8;~hf9Uk6<`R!?1OLEyu9|8FtjZU2$1a6y3ETXY^LSiqJtp5q z<6I5wd#`bJab$s$PJUr2pO5e^eA9(Rua0VVWNgOZw>4k9$3~&S>bPBsHbF4_y4@e; z#}l_2CruS9^@L0}Q`Hw;~U9eFk2d;@*Jr&O1FrAefg@ zTC?YnKA+zP47X^u)1eU;rz`l^P+H!+FBMp{1^$S&b{cw~&<^E+Cs~NgIlhay#U2uh ze;2ElnYNPNhEo39PhsII&%Rk$E9Sb9B3)D;SHdF3yFq2tWmUc1B7vgE*%NQ0fvr8N3@eM1!Gwl*#sP3EWL7rMKW0%WvBzoa#$rBaW#u9FT4o3HG8foG%|LaylW`JX;n&~0z`WIH<9mDYxhj}~ zCf4K9(I%C)xDY^h_6V>*Nq37p`#toP;1>j-=3q*&w~THESquTAO1zi0IWwF&&kq3$ z<^brATB8^-Y4so1ayyBZX^F`Z2i|q=D0xLowE^$Ln`(4eY~x;L@o2g{1-F6WQ-i*o z=Zl8yL}7qW{#w`1XZGUwD3y+Gm*7VUZ=VrKlaz4PuJzxP`NrzB*;8$HX zwmA@Lyu-?-od&cF2=&V%_F-GXe)cF@Ff0_MN`Xk=|Y~)7^q(Odg0$G*6 zYV`ke|1-ub6lZtlX)7}$Dz7>>PdpV{nfxXO$~4!2V+NV#hmNc-#~1&LsT5fD1}ECA zp@Hsw*1J5!uj|to1Q3H&LR1NgaBY)`J8KuWz6e^fGG>p~d#tV}cun7*d9~I=RE;fJ z{gmV6z`v*n(^qI)r1Sa1I7Qfvr40Oo&9LturmC3yiVF=i$TW3Q>2JH*-rlP0b&Z)Z zHx$e_ngT(gXA=ktzRXaTFb2)mPyA>kzGVuMP?TPR$aTHTbEATir{6BvKadID78EBadRx}8`vl{W zJ6~YpM70A88kr2)Qz^f*cuV!F+n6n}Dm>zdVcgq#d|}cv^|yKQGuj=H_zk!RHA-pH qYV58Bg5}KOp>1f*XfYY20;sS`^*(JHm@WII0URC9+E?3QZv7o7SoZM% literal 0 HcmV?d00001 diff --git a/images/flow_to_grid.gif b/images/flow_to_grid.gif new file mode 100644 index 0000000000000000000000000000000000000000..f78228cf5c685f3dc247eac77dddb8f9b84a5a73 GIT binary patch literal 124025 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

A{+H)$o}su{Yc?g0`$RgX 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ði_h7+sjZvDE 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

whk9df+7_D!q@$EG+U0#1K<`k zcea4Q<;pl6T|+)WIBEd*wBcz;5N@Aj!_1Nos5TF8`3ofHMg51(r7cMS{?yMIAl|$j z0Po;%_}3rVle51M2+)83O3ohE>gjR+iVM(K^*)cG^v6{jwgn8w zHDN(KUPXjITRzG{vgF2uRWa!^6x{$Jl5){BDM(N=(%F_IPc9F7X~=G)PTu7G z&$vu2UKw%nCkInVQ5TbK@#f*rHJwD&Qh=qE0s4*c3kq3|LK6#hUBJrK((4U6g~Lc! zXjt`Tl95vBT?dLk4i#>Qj#U(G_)clb9MuR>DtoIRWJ=U7pz#(uSh&Uv36jb%&;&;3 zOHFB{I>Q?FzLUEfT`<3{Go_+?yFUG$JefZ`Y*%=}oW@`G>j63PA5+19w-%@@Ql{y0NufO2IP zB$k&b0}|0b8V!kDJE@2ZXiDA-i4Smh91Qg<%;V&f zdso<<1va9hQx&ZC5fGcDB2IFO9kx=lu5Uaz>47|GV5+x5RCw%R%q$}PGEF@SalM~~ zljl8(42h1$@f-YF25Q!p~KylVR@({qXH*!6%B5tic zc1;?a=3{N@2_@*SRnx2LZ*jKg|J9l<=7NLve-S&{EFK;BwpJa+$kvt*x~XYYALXa* zQd@C(Uf1Mp8q*Qgs~OhAUEdLf{!^@3*cZcE9n~)?q($AU3NZuqwdoSM)vxgtoj5Qt zeiMeW+H#z-(d>pa5OJq&9Sf6j3wRViIV2Z-Bs!vV29aFOJ{ywt&3Q5BeH)}YD@4T1 z!>>A#+gv5zrg@6yqI7W^SFV}=x?fV2MZ4N;R+`y0^jKbFfXu7 zDmaRhKl&c@SF?chgI~x6y^#N{taZD^iV)`oEQZFt7>9JUpB~Ge0B4M~9_id`X9!J* zm3sVx)WU44yGo$IFku`IWy$zLmaH^EpLf^I7lM^NT>jJE1ghC$f;l7A zrx&m!YWE*>-_&|pF{JQ^#xm}Sqo~qvKr*FHDKULEQ0H@8>Wi~d60K~2Za#VH@q8&6 zt3RIp4lKPkmxEWhcf7LbgEQwsA(gb0Fxz!pbcks2qoh#<)9--Hk3=BWn;8S*=&kg#S^QJ7YXg@h6tJ=FPAQq*7f>g9qLRN4GR z(~6E6(EXGHTFbIY&4cZnqn z|LW6{#=QAVEFPn*|5aBhThA}I8N{3SMG9y%C+X9iLVvznmF;g>aU;gw$p-M(~m)%`Ui3tmJp)Ez*mac>l(KsFC3l_QkJzB6V`!J;!tQf-}~8(4{VPg(~>$!Q}`GB_`=Y>Ok#xrxI-5# zo6Y*soR{xcKf8#&?o$=bw5s!Enq0peZ&Ug?7w<{70p7zy_96n3$S)?olKUBvUg7ow znR0VzCU=#IGG=1VtSls6a`*0L34c^CwE7B@QvQ=HMBrssO6QU|=(XhzO(G)ZT<>Kq z>}`NC$Hi>tX0R3Ya^VY@aetzdPWcTT`k*glW$!fb)EyF0{CxHYyLc$TJ)tRgS8G>h zU3$7x7xz#{!A>T6XBtK#R(K`=m#-`5jw5Tv7Sq0jDONupmpc-5Xx<1B@w9LALyN(- z7VTeFtPH()Xk6l|Tk5iaK7SQIk78xtAEbidneAxBk6b(&DU|7JdC(^27dwmVu7Qen zCUb1bjwYo1&1#k=8WeSo2II1Y#|$RwZOL5v1#a}FmL{sY`hQ~Rwno^GQ;^T(YhA0h zSH%=kDl77Sn}tPe2=FA7x5b0K32!Fe(0D7~9{w)u?bxLGp!Mu{O372yZdnZ0*!12l z?_*s!hWbOhdUs9O;X;IriqVNBPVceTM8|(PAtOSMwG%91h_!_O2syM#4#mQ7>2Y?g zJxQLzL<7euwXPzjGB5B_zWyW?{F_t{4nDK5;?G@&8@>7^fJrj$PC1#;Q`@CFp zfQW(&hpBSf}{pxDm^!_w!rgKMf=4v|d{;ZI+ zYftsn^=HKW-^y2A2Zl4(OC9&;^@&|a4zF(3*6%Oc>15bCr*Fz6zmVI^3;|m=Z@#lI zAK5HpPBIIiKMUM;RFR|8=^~I zAyMvNW3pVnS`=X_tNzLb!S)5u+#Ob)fzTD1^sN!l(0m|jDO6?uqAp*xBOrg0LYsu=p%D%5T+ z1n@0XI_mx61ugvwP=v?Law*KNA*{eUOqVSja2{+m2Xl=K->V2`opnk9dPsPF!d!UK zvA*k)ATZ#u(rTw}8n!o%wkgF6_XdV>(nb1jg}+q@x10OKVCCefhHo0J=i$dV4~qD9 zZXeeg<*nlAyknS`>=+~!{b45x0E)KZiVjzc=H({PaD0zL@$o#;u5c^TjK|)>$HY34 z`N^!booMhYiI0=TyndshPmi%M$SG*&BI10>O=T3Q)%sqcFf@G@wrU?KS?E#OC-Ec_ z(ryGU%YalnicTkg67i1h{l+xV4$k9>NNTWFnROLYbIB}>d;)tr&ttVE93}k0>K^~m z%7_AqeLVH7>vID#DlSl-O2U&~yNPJGO6!=s6|*yCo7GY9ArI(+F5$0|4Ud}G`imu<4KHI&33y3r1DH+sQKmg2)> zmLG1!*K6|D-B>KiScAhrX~CG?$)I&eUz$@3MXf5|qV{Z2xqchWw{LR)H+7i9^xWQv z0+zx{mL?z#{x9a?Ym1d!@Orisj!(mzMxdOw_cm=8mIf_M3orvHANk-U&5a-0@cqHCLOVz;g5Mz2zQZsJ03`r%3=S>IGz z9Y^abqlzjsaVRwwnGugx56f1KkWPzQRgFPvdabJYAYVNkagzKsQ;^0V=~Lfs8;e0r zB#a3!QY9x&vk#gLjTQ~N^>UD2IWuWFPoT!1#>LPg%Q*RQQ`%B)P)f7LiU!zmtGmYd+ApGj*m5T8DvbD;8`oktO2L&rTr{o zOv>1*(Zp)zPxT_$e$E~gaiE?jm0jYxU8FHo%#PCE-_PJWc+I2n`oVy~nv?d5&+rMs z>o?AN`UGzb4-Aa2(@k@X%*S6_^66V^M2QpRtnudH24p&E=(#u>x@qX!2AF8)R8;6y zV5mzXrAzX!%GTbxdy!}YD)th8A=AhgfP#PM>FbzXAL1qUZ zQq{Q1Atyx^o?bqVit4WtNy=E?uLc~Tx}>XC9F$9Suda|x(?Ruy_!U&&aRFI!nSfrJNE zN+T+(J1W6}rMQ|+4K7XSLu3abs*4|$tBGp4scf5gS{q1Lf7rk&+tH80VAeXC0?;Ff z*0GM(i5t|4X7w6lm#A^^=a{-^r5BrMx|3dd3YVz= z4cE{3;E>g99vJxwFE-&h)S9b0rA!>Xww z+bxg_p~W{iciB@uIteY3MIjKczwCZC!|e@xQ?`q4#j zw~gb_+2$U(J(3(havVfuj1Uh*E;+nSAcC2H7?ll!TG+!TG7BmiZdaJu9G)U7CETti@3ERi zJSSq>n|2r=+RY%lW`xpAQMR8v1jchklCl22?EEnU3n#?9E8 z2X@E|?5^Sekiz}?s|R%O1n2DUx3I&Vn@ODBs$^2DCcvEq)2suTAq*@HxOFkovPy`c z%9bC@Og4GWfQu#aa<$*eCjxOGg0(_~%NpXvxiEvAy($yg-B#sEQDUgpwndH0V_KW+-&8QoFseb_Rclq=#P>LoZ;a#T;sod0uyW=(39bzmFIy2nP_vpA zjbULLJZR*l3jZsfp25!XGtD_gI!mg}kqg7sm+jLfXCvOqMsMPxzA~)^$h}d5yw_vF z2UPm&Ie@S*KO>G8Vy_$O3s``E@rgrxA?v1%&=p}}-8lTc-aXn-rLPGxk2oRyyz zWcNzff{gc~!3H`n{M;rct5ouNY*44sP;icv6wo?2S7Oj1xPFMv@#!^w(SwM?A14_N zQ&V)#T)9+=i&a|4N>6aP`4`P#JBt{{3Bum>Au76WYK63^5lEX z&Ee}jTmDFk0J!~#A<};=-#8}*T5MN-Tp_APgiL*a}%b__`#cH+s& zT|@FBRlN@OI79H*oF1j+TRE|0U3lzP2Q7@N7SIO;s8%U-!d0uewlGn(fg2b{WKh7k zGqy60Om?*#nR6Y|5Wrf6Uq^Qd2h=}<1V%MKwn9X;`txYkkfVyX1lylR#{$qCS+V#S zzsgv?jwQ^^QEIUP#21hI!A1T)p-;?vH(!zbfl zJ&BsOcMb0(i6T24r8;!-C?R+PdQZyZ*;zYs7rG%#&Vo4pZvb8z=CV;gb@M&9ep;7w&J$`}z*Ju?8!LZ~r_bRkwuH^;I;nio z5iGvwL?|o)wWHM){qmn_&EGkH{Dyy!V9JxWUhBiIRy?=ByVe)F_Pe@G0e|5bBY)t&S~JmbC8_jLaI05tNZ9)p`V@lob0y5p(L zT8qm^+1;*x$2a&jgqXmtsk7tTw8cN}cNs&PpX7GNs=9A+`(&TWo)jJ4%O81bew6&x zfOsbNd!MmKd@Ga7?Qk|^U0!PA{A}}1ZTabZ7wL!9`M!&l1$o1lf2^UCeV`L6MJBD; zSHwh1V10u=My>jwR#}$2tn!vZj~ZCNtQDR@r5rh&HGss7=Bt}j*vHeX_6Xm2JfiI=9U({F13t~S!feACQ zo<^@c=SU%q5}&nhs~im*icgMF_WDkbu2gs;LKer6#&*8PqbU12DUs$c2j0nwlKgYB zq(^@_2#0o`FEx1Jzr$gnr*|4=WEY7F-C$!&byOp<5Q&Gs;2>V`1Jdp2#-)VY(r-JC zsV~(hvjvoru#a`$qyK#JyZOl@iXMJx(2)A9H2vO(deV$o)R>c_XhX+XllA&lw4s+B zm9@08W$PT=D%G9_iB@*=Nk&-emG5OqE4^PL&!sT>$nU)wyzSWWn$)w}{fgi~~r_{-t2iyf)7)6$Mp@KEwPg-Yr4qUl0U( zFu~~Vk|ljj!9qm@XoeOCv!3*ouzG$LxdMZje)Uz$JMwb?s#t`nL$p5nrQ+YBqVT9g z8vI$Saaj@g{3j2!R1Jz-hH_&DK(FazO`zS0)he@2UoRm~GNg2mR`U!Kqx%C7!{6i~G8c8<^fGG0F*yF+rbcF}t6DLMI##KEX%Ktt$QA;^pr zaXHAvCG4R~X5LwNIV8k&(wX0}i580P&1pV)*U4_%R!xVqyV&slaPdduZ5F4D1aU0A ztL?8GK%4sTK+^lcpJ=IU@OZpPpvHs^VFzcs@MvR(dfzswg7IiIugDuF%`nk*zj0>w zCX+2!&_U?XBgrIB@kn;~3ex6`ZC58=;=gg7Hjaq~I-y&YjIfAyKr$Kr#0TEFOwSi_)f#u810KOhGD)^t%>5-ltz2_qKY09zz& z?ISOLe?SCoyuTC|TM~kKcHDf~p?QHRQNZ(Czj=^XN>X1;{rPxv^A$ka-ixn&9LjjR z1$oupPdj}aDSP{kEU|r%Tl)lVdi$MjrhQm)`XnLn_6I8|dQ?^WGzD?{ljjwB-0=Sy zfubiJw9j(ZZ+E0-(9^!tXZbg`y9%V3*(j{`-~Sa8jrez+O#Ssdyn((=Qkt)L^v=Ix z8LC-QPrAxy4d9M{Kf1pzVy}Z%n6dgM`bl|;N^ZUMB4GB;E#yzR7-fOH zC(HdwnLyr3;?I+;7`Znze?Y>C^w)Y8_be%vz>OK@OXm8fbjpqEjnsjw|FVPKn|q>` z6SMB(^W==bJ>z{e&+_cdt-;o65{sp33%yP+wz-ppF_qh#W&*CGsBqe0-mJC&qt_E2 zzR}!PMeZ;QE&xP=fpEw2KQfVe_6J^KNVbCEt{v$H?Z+~F-pOqX#4Zcc@bRgkrD5AU zt(}jMQ7ge{|7>@=N30GjncyYEp!$d~?iItI57K&&nQ}DyfVltgd06f)+X*>rq9HtZ zF`RwNUQG(ziTjay)-rP|LXg$rpgh7Lntd48q4V5d!ri25NMGACQcKE!vOY2jmpNzK z#B|S?tTBpi%ieV*awM5iuHU}DmqU%m=$c9;UcuE(Vo6L>EmSYP#o#i{_HPJ* z+^N`HGbDs3x~NoBbV#%8C)VJ7gaKkv|K(qO{)IQf3Q-hfdMx64der&`;`#-naF3sG zRk4^f$mPTQ{;aNqbgN5{46>*(vf_SS2I#G`rQjkfV6jKBi=x}%pb8Pm1v zA>hU=Kr=)g1u>Ap)sRz$KedC4N5I$o66!`18l>R+?V8yunv;GSw=Wbr+cmnSRR0;l zul(S>embX@FTkq_hwVw{MoEAClK9h;K&$b)f8)>JCZB~TU!~~>ZpYoL#aY?M zsHN;RB~mUXzW{YaXY!B16y(noZroI2 z>Vzjk3EOmWtx|C^#@IMH|2UPa*J|0XDg43fS#L!Ab?LHoH!I^PL5X7Z=^1`cG}50q z&nw;xN$HdAaW98}7Ii%BZ)6`QLBvkEWJ53YaM8oKW|oGOxAO|><8PK zH8Oi^G+T2&`)nlhWG^#pEbG~R*4bWC9yGZi24Sb3EDS}^@@80N=Qc`b4ASQeXQwsq zgIG$_7Mu{2vuO|{f^!TJv5z2tW*_imRugoC@`LZ>RWA z>IETA1%NP*(-q z&gr~s+J<}z&oLS7;3C1ZvTXWtBXlX{enHPz2@!n>Sf&J5BLUyUQBnq>s!=GbQTk)G zNL;#z)uc!nS>7;KF2z?tx?eJ|Uv7e~podlpIhV#UZP()10xCJ+#hd}T(c`&r z3^ooio@ji4G+jfOGgPFlm4wP!hoJCe; zx+*57W*=F@G+yIe?!C!r? zfw~>9$V8Q7kJpQ%D%??3yrxKqX_Hz&6JAae2|sceQ!^USd;+f)n83G@!qTX$*YN4& zSySVGH7S?h63pK#^(BMjoG2#mHR|>Uq+c3Yn+iB+mP;-fM)O2DLLT+(MD{u0z|^AM zZ;ady)vS$h-nF)v1)8aBu{q(JysBcINRD{@tu=O=ErK8TC?za=n2m4CK5~UPjvu6$ zWh!tQZh-*4T4^_Cix5ac`)x&K^`Vo8tw;ldPj@ zKqMLbCZd#)HLUOL(vl<14(3xdRiGq8-$amPF@tEkY5tZIKHb}*qV`gt&1xmksy(dg zoAJCX!C9G8l5Tg*9KkxFw1|E8(K;<$x7lT``*huQ9}$}B1EbKvezZ#NJ_!6&s$jMG zFL-yi=RmUK{>GfAH_%rCJjEZ-dI%)wq<*vV_}H-bgYu_agdugVPjiQ3<01M;vd=c; zVKe+3N*V6b-_a`R1W@i_s`}Uk`5WNDC*fgCK6x|)je^2 zK1*n)I2><3#9TzEnnX}_JkS6eSpGh2H8Q*+gzue1jsOg>Wx3h!`e1fPDVUB z@!rjjT99?UB=b&?8?&++LHCWOX^kc2dgX46<=>7KGL09@5s#Oejh6?FSLTk>{ZCAm zGC%?#1v~}(Z!OKJbXb}2{;!0jAqv!M%wyKG=Ot<8{(9!X?^=P3v?@{o(D&yC`=G;x z0r9{-%6i~{u!p5tK$L9^F4#XYD?2y<4<}U)fDg(kEeitSC;?*2YqCJ#0tK9s+Sbte zMv1Dxw(d}1{?np|r5OSrBMrbA8W{#QNH)(b27|^W7M2z(3tKiuHpRf-HhxIqPw(^q z@nzPJM!+HfyweS&0$WG?F|Jr)1;HFp?n zI9d=Z^0Aq^`p2j(t)-akRV)WQT_E`3=3`~9^#-`s2>|@IuS&snyB63^8R{x(CF&)M z(Muhq)I!*U#`{b340-hzI@eH@(KTf_d-R&E)vHa8^y#n1L%FA$-GAhZi_hiGI}{*8o#1~Fh=5u8sv0-bVuyZHi9DXyG+SVl7KHd z2$+J0zQeeHm2P?gQ+@+)wV;Z3ca((^5I}bD(Y@yi4xlKc^u#Y3c^UOBSmlOiN>&8A zoRxMs{rCk}$%JACDsOn7^vfTyRx$Q{joWyo&GutIvmfgp zrgJ{v8+K$E8Z-w58gO*QzzSLa{+j(N-tFzq==VZsG|H2m3_?UcOTVXR6K}K}7DcY% z!^T2=pu--`#-#d)oQI^i7!OF2Vl9((+pd@pIy*WL$x9Qi?yCU!2T5iAOQ!}W!C*4nu-+P>{7Tpk+$Sd*a4jQ4yPIRh|Lq;@Z8Y2 zRbXKVBu6RF_gzxOr@*KEoOmYpCwoNUAe%kB^m~te;^-WxdP#zovtsGTXa=S7kFGgD zRB)wgXu$Yc##(#%uq-_$#{!_a zak3-)0d}1u=8qZm0-&kZA(z}ABpx;RtM3l2+8zfn{wA0=&{XX7%Ah~27;cme?Rb}A z3hH{1%gEWiAv0dyhq}}R_3o_k3-lebyMlV4H*1HP=Q1fgiDdX5N9p)cYjs0EQ#R^{ z^JR)_N3JziK9CY&tAxlvKURgwSl-irsNt|RYnlel9G!;u$ z{S$#uVOPE44gVdBjqowXA5E*8x;0MP;x~xT>E0wYm0Eo=7oL4P;MO{@QvPLNt*n*! zblsgHQ=HVnR>!Mby-oI@2&Y0N8as0SwJZcekW;NlPQCluD;GNW%;^A;FsE}*jQB&4rrGo zbgQ{F)U;p_%R?XedIvyVc%fX?r0>Eg%7E+5tmKg-F^ms-1#s*ZE&7Xha{~@%b_qiL5X{thQ&eiiXtU6MRbb#CG%&CFB@rn z<0YgiJaWzkACtQ~*ngJ<^xB9|XRm{~E^D3STwmxVeqCeV3N;;nif`?BJp`#=V(5(ZlWApf}n!)|GE%0HH8J{F|U?j*4&#f}vt zdU%NK$y3!L9dHHjDD-rG3y{z2E3%o8_-E6WNq^_0!MdlC?30ZB0~G$U2AW`Mr>I7d@~IHj z>8>)+dW;f#i(ZRZ#7L{wbG07_Wmha$BBtveiyRw)I%=DVtv}8_;TM=*314;$Zs9)gOzI=gEk0;drLUB z5bj&c)IAiRI0NBEWVtz%Sbp3LdA-pKIo8>6nH*s8IkcF8HSOn1Ua|PznEh32>RW1_ zPCIrO(kmNk;Loo3j?x~MYs2%CnrWuMHMNE>f$y;?@9UwjsUf6$R&mQ*IyGDVHlzTP zgBC{njVGdg1-l;!75Lu1Cj5bGi6;vwnOF}IxxNf`ka~_y2`_KBwA9RAqGj^@Q3g5J^BCQxikA~dFFLLlYU7)#9CVJ&R22~Q%^O%*ZY0(*JMaaVtD$M(9Q+r@*q*X zr&{u4eCfxH?xT>abh_KTd_(lnE8;qw?DcPD{j&$YL()lIPq}fmRKGLnp2A&r-j%CM zezX`)#1D*rQ|-rm@G?t=;5YG`LDF>+KMD8>nC~3;i{X>C*vRI7%KGTf=CgD)g{}LT zoXsP;&bU3dSZ1vl$KZ?KV_j~C%L4o}5Zd$kS0X&O0>E$hu)pjc{C?k`q}kTi9H323 z@m_cSrbTUu4JjuSiFnw`+e%`+w+q1=dCE#LAXio3-}yqVU^SM+9p z*8uB%1^2OEdxgA~-=G}!ce2pYKWPW8k8VEU+@#%0o4#UcS>Ri|fSk2}oH<~@T>g>} zJaXDR0KJw8r-_aHY z=%{7t=MF^DVMXvvYo86scQr;B|B0w3jg*awSU_q#!)O?_>b_7{HbH^Rs0|z=BZt_L zBkU2$w#ZcWNJ%W@?^MLO3i4Yda;y=dv=eEM6%{cPCFdAoiOX+&sry)xqu5Bva72$b zO|wQBWowJ-ABf^G2EJC8a=|?R{#&1^@ji;B1eJeag}yZ55kn}OAXH7BIyy!hbE6g_ zV;4)1xm?i%zKDn&WDzEIQzh;OD>g_ya^E&qwl(IdZQRv7g6kA9cKN*T06uvDDlyTU zmITjp$ByI1QE|qx6}#vQr!0@AYe4-C-uZ_Owz7oQiOVfphr?* za#D#=?2dnQ&wyz5h;}Xt^@KT!b2N#2S$9+|Wu!QMcOd>17K#d*)G-}%oe{-5Z9{=UsR`7$f{W4Rt!dYidWO;Q z!ab=CTdDp=(Odzsj9IasZLuRuvD8wD`fW)8%Sk*u(#D4fCL;V2boMjY|oLOGH_2IHGZ)(UGGu8d7Od{%NhLX;ZeTNi?W58gvX^Vq8|% z$z}S)Qr1*v_L_Rmp-IN^LAFdlwwzNYcs@g+F`IHZ8zdDQR4&(@mFZxb#9oj-@Fdz5 zFYP%`TC-Hbf@y+emR|c|W{wp5sA&ocFOPdy*ODgM&nb7VJmYXQL;NtKpe?%SDzbzo z>cjGT`Kzo&n&g3i`@Bu=6n2iBm4md8{#mvrxpx7%_oF%LZMl8Rxi?bD{%v_9rs+>n z`90;DzXDLdvrx8p1>LrVCs!J+St+Z_$iJh(-^!B-uk-k_3azse7>`nt0}8W7inOi@ zbZ81^OcQIbqL^v(B&3Q~oC>m+i-D?zahJv0G}@Bw>C&`XZio5KtwmRdpviLnX}r?e zwqmQ2l7C_ayU|%H*VzWw@mw+4qS=W~?TO18`e>)3XJc9TyvncfBQ5c9tqzlwUgUf7 zCb?)P5lMqy(wf=E6x2zTsi34eZs z`lL~?W`p`hdY{U*VW=w>&fW)8RgI9We>#B#h+*;#&%?QK!x8#WzWNH@-;c$Mp3q7L zR~1$!T2`D`8*h5OAl?c~35Q1^MJ_Txe}9Eml2&sogk3&@W4()z>+!pH$QV_87!V5O zg;st#2Y<~7>QeKXNGth11O8zg_DPd*OH(EO+XkCn+v3*O_7dY7{vC2bY0@Gk0s<$L%X6(5L7M)C>Zp*&!HB10m~8#AkPev zkF~pz-UMD9`B=Yfu(huugEd%KHI22+EtIM`a^40Uvx_u#k{bbhAm@~Q1OdC~PH zsB0;wYo()WZMAFtrfY+)d+X-^$wlY_2O-_{x%*-ju z27<8z;)*M>lA~oF#;_|JV8|K~EKp-dWT`BqzOxSqk*(_+2?b$^0&qsBLvcP!V7Jdq zgUTeZrj|x=TKK+vn*q*?w(Tw-wDul1tO#QNJZ(G?`tx@bxcUU^=JLw0P>}hF_5BeI zy{|4#ZB#!_9y8=o)&K?e;~z&E&x?fucq|$QWWUd6rte9xOek{jI;0?2@8AP1z3ySR7yTMZ1(ufnpRq@x zql&FAmBJ$waKaHl+(IU1#ut_aQ1(0kfSvfL)*6=|$8(E`$G|cTC9iOx7LD7-JrKwC z!jX+#O1HKc`V{}5C{Ynwo}HwycA%C_%15J;LWgsu9w()KsE9UZ4G2$H@W8Xh6AYEw zaXiz%ibxBw%mQS~jY%ox#KWQ^G8q!3%Ca~&4kNOkx6^RsiXJV4-{UShIg+3Pm-lnx z=}k)XIZ4g>N@R`3I8zk>WAK8f3cNh-+S0V3{5>m8)CWVaz#Xy3E{ZmXv!1DEEU&6|aP+ufE%eAW zZ~uprE6I|5L3Pk{JaaYieEacnea{!(@6{U=mB)1_G0XzNJNQb+nHzfr6+Mxs{*L_& z^lO%Va6WqOK?&Kllb&ysw?`ea1F^lG(*9KfBj5k69+$@2JJ*aK;M{r+bj(%>e*QGJ zh8g+uf$pT849p-fDw7!u93x(Q+}97@%wAlH&MVp(fh?h>v;HPDD&%xEpj2Zh&^BLr`7xI`V1d-m+Kk9M+uejAHP$; z){zIIiBI8&VKV=KJL2l0qPrUX0)jsTr=ND7=!*zO9f$FT)&G&k`w9FdM*S211NZc4 z#7|N{e%oILkLM8=6o&H6=UO&X;lEdv!&+`PVgKwI4mO>AwQ0G88EIJitV$z2Hxjz3V!)J`~!$*kXyj)Nl2`SN$gZ_Tnh9g*a$i zA5HI4x#&DyukPiPQvh?IuSRgVKf1`r_vN}xX(cUf;T`1S=Kc_e{h)KeV% zT7N8+*9$0rG3NUZRWa0^)))2M16`iNZm&PnlFaS(rwiAanFW8Pxp~$)2TzK$wqT-p zza+x_j}PrVx3Y(|*d|?68?k+}@l)v`=V)ILDI{ryV{kd(b@vNxL~eV8+a|57OPX|J zXnRE+5dP@tlLX?m?N;9MT5d{fq$ zQC;2*QjnxAxor_Z#Xtqf&OQWoe65N#wlhUkg@@vahpEh!D?a1n(c+Q*jYSB;5+f7Q zVNP{O=Y)}m`kd-UzE{Zl9k*`xFFD#{45ow`P>>_=oNQ|3$Y<8$bP5J!s$Gisxtbm{ zGZyNQ#EINL?1`s6Nw5z0K~zHku6wwt(J)_en}R5RZhWzMNaQ4-v`Jx46|#vJg5v`c zGIn@Ipf;Oa!CdCHe7G2RG#lw0E-B&|&lV#++UC(mtW?@VPTXT4Z}bODBt~d-uYq00 zs!&Qda^%=d8&NKu_JkQ`6p00eG>mNGzgC5*D4&rxxBC)%P(%$a87(j^pV#XS|SB69`*W~@x?F<4^wO6u(wtW^FnPpw3YJi-j@ zwtMsmpvW1H9H3;Gz;)BiTMbWqLfIj%r)Edv4L(+S(If!q5hiwlt+qRMsq$d^is=C+ z1ys7lG49T9WJqpSio2dd1)l?QBd+mZuqAK&w5&-aZEj!0{>uGBkv+YX% z(??#@W>ay6o;u$Vker<~&ONOe1mV4|2%&MWw zb?seH$K8-ZYtUn-lRWBLIQqE#lj&kJ>n#Dbz=yZ$L8r(dtI6!?Dl9&mRA?9qzktZ! zs%7ifpLf1w`{_MB_Z}!2kESnKUhdvW*Hd|8GFT$}4cMvIS+wm;1?_Hvd9*mN!b2deyF1-ZzC``! zQw*XaDNZ-opNUb+2F(YJdDop6SKu+{T+rpM)f5^px@vq#o*TdgH5vD^=S3+5-uFD1 z%eccWdOzHrTka^DDW#toK!w@&Ny6K_^@bF-RO9v@1({B|82n31-`Xa+%T!*-&`4?8 z-Z_!IlA7y>g_R)TJi>rcD)st{{@^zPHp4g0+y4UETb%e^xNlfypPtu#x}yaz4mIh> zqZTB#&pR&f1fPBioym}9X2}c&3xows^ zWopU+g6D~zkYI*V{SxQGB^%7{9 zOS^>}j-#$7M=iTgrEn;rpe!jTf1s#{QZUYx(|1%gM5&r*0#YNx8T>UQ97CmAHDpZG zpI>Uc%v3j3SG2+?sA5>pGvHQ|2+_>&rI+C=Ww5tcuysGgx9uQ7KyXQ;pHpU#%aVpG zDp;#kRR^P$a1b1e8-i{PN;3&`r`GhuRq}RJ^u@6Gp(1H7@Ac_hmF!!?vwWftGNNbI zP$zTI!Z1`Jw^A{Ny>tYmF%q4`{h*?Qb4=i`sGq%&d=}t{60nTzSC1S-sSRV)M%80K zacSPApnB3`P3vP#J!3l3V$dxyp(Eie2jNHau&PU#h+~M@K_o7Hmf6bXp%{l*sF{-%J#kh=8v|k_kDODnrJNiUD`rJ|NPCe`%qqt5j%}XB7 zD;Zyni(2DC$xQOj6z`&9C;MTB1NqxrhhzBXpdWZlWhGI#< z`K9D>10p;9lg@GC$2Q=PK;hih@ow;V`ttb8mV2aKYm!D=ApcU}zIwRvvdS@cC<#xT z)Rnwqc_PnrY+G?0e@~p1Q?yt)LgEnRau`d57x%_A(NiOi$0_bH9zy;q`87?7xMYgt zQhMBFdbWRtK~y?lL3;g?Bv}C57SE4xIStz+<7spzKG4sVhT)=xMw*pkIf1XI7nBZD#GQ!;z3+!|Fhy^_bNCT zkcURm5?BX@?(1U8awV1H`bu z;zH37&?P~!$huXZvCkV{xyV`d9jBhLXoe9xNA_b)I+=}Ek5X7Ixn2@p%ZWqsQ-DPb zJ)RLvJxIM~;LDjwR%2f;Bw1-D8uHEP5Fb0zC z_5}W7DzaQ)(}!IF)2>>=0;s6t=r6tg>kci%IGVX-UzcN6TvD&!eyngtn7wLnCV3zS zwzLyBN&9s?xHmE6pDC*<2g|#@RDv9;m=IM|0M};w3IktvAlz}Gpo#{kdV{n223j(0 zS3SK!AOrB0*mQCDUD+t)qM>R$X@`%ota;vBy@lmWMCn`H3}Ljw{ey4t_aX3USuCSw z{9}dSPMRfh(*st4{XjWX*28h|sCAyk`4^)Ux>swi2N8fcQ0LUqcGS_Y)-m4HG1Jwv z%G9&p*!=Ij|4V=hfE@VcKh(7ZP#fO-C;M90kLd}+0oD(B|4)|g3PQ|!A%J5As9Q(x zj`HRj82V+UrCUyX#P1z2ASf~rh+{8@jS~?SZ}p&IeX-&aGTwwoiveC{=39YsBmn6J zW#&j9k#}z~n9xeT*pE%-IQ4>9=;nMNRtZkmN1PNPNN0a{PgUR8K-=SvDGU(OKHv03 zzh=1%G{Zfzj`{o;veUHp0BbnR-w?w3xx4>o;h6X2;@c+M-0jm>%KAO89-;-22nNBA;gE=LwWRX#!Fv#m@ zZM30m>OHA)xuoeq*-Wu4(+pt%S@~SCV($j4;vckFEZ=P0YVi{+80Izfip>gAJYGj< zZI%}CB9fx^ReHGP)h-KHgR5p9w?bVd0m!Gzk^wI9d7hT={H+fG75p2IF$)oK(vprU zJ@)w$|0De=c(V|Zj&7xzdwky;Mn71No|=OMP!}WC32vfVpnB^aO@#YnFFP+l1qZyM zWT!s(vPbNW<&?5bGG0rpm+GBYh=*Fx^j+t$hhVHC%ynX0jGgRT$L$xEI|83ywVuO5 zB!~+LKwzdvY-WA@hOS}3F8tnjv3i3ZRIur=OmdSp{f6pn5L!TW9A&vc0^!WeCm~8c zWu|&G_WM~Bv&Dfjf|+~inZK-$WFOKz5{0H?54E%=;a+dCA`yrI6x%%2#;n6?tu7G= z0@k2|W0X7q0ZXELDh zhSTiq1NPEIp9QQ(t9@v-i8Tqt*pWE9_1Z(+jsRQ`uh8BtVmSkGZjvZg4{k{GUhM%6 zI$X_x&b}GWsb-O!$U~gtJncl4a0KPSm5=AuDQC+KRIZ?@8dI&5>bzF0@^AJ$#A#lE zJ;rHw>wQez9SGpNFKmp_drLI@I*|`FzCQgHGG#zp9i@7vQJSxDMtu;Q@imR4I! zxrx#urBagCAKwc0)5rur8Ms>Um#7G+Y;S1} zk-3q8piJt+F3R)Wf&sd^U~#3daO=a zPG+--?zPwt8=F_nUlhIh5sL$d!4EUTkGo~IeItUT$ICl9r9W4XcS=rVv9-6=y=S`# zAUb#R5IpZ9_$PDJTlrM>&){*W?Dx^}r^1tOWSE*4&QsR!{4?agog}=wYxsJPf=JYl zPP_%pzFE9nl*N|jbs`d7f7llh-}UW%+M`u)nm62j(B=mF{k8 z^@&*1BY^xCv?OrZEI7a~1}#a1`1Q*&Tqhs_sf7S1bp<+Fk8oU{!dvwbIkG_az>Uhh z?iysv_xnTFpy1=YZ{3jAQ!D4-dEWe{NwtVSPL?62Z}Sh=kzJQg?xE7t{Uq*W11w*s z2~__mc}^NYBFr0o@aa9! z50e;atgYUc>jexmZEz{6%b89g%Q1i~X_~vbZEkRX1k*C9T%e;JSvp&|Cd-CUi6j&h zISRB3tguY!$;oF4E0)6J_h$xu$hx+Et1ZIV)le zgUo|3^hl%oyb1tr=LmM6X}nKQl>zylI<^hMri0nxj5Z^06Q2^8soWOS2VxJhsA!qW z5LyyFkLG`Vs{m;4Q+N#S34iP70s}s9yReyiDBfwUE$WivKe*Xm8RKhv(id&h_vjj* z2RHl3?4o^XqUK%8_}3qS7abc!AN_~5*3YspIuCR{1}=`T|82kMIz@jB-q-qey>iig zIq@;{V*J~`>x)kS;#wF)djmvw*@GLO;$o$>wlw>t*-$USjqZEu`oDL$y$k|T`POUj ziZlH3b8LGCEr!|dZRm!|bIQv)Gg24dhWP_NVqTf#M=q2cPu#*SqsGi=rAl0etVk^3An=0%06 z08sRcKlrqF#<*-!hyR2#ku>g!5wjpE;|?PN8+Mz1 zDfe$_HfYE6Ickn?BO`ne0yWL;?7yZOR|#| zIj)dE{MMO>?NWuwt)4*Uj}Zwl%j@YA3shLAKRMb_F^g+vm)0nN%=Esy57GZT(lF8r z5A3hR`C&R*b$D|UJ3u901bQGsemxicRE?7HRg7PWHFdS*Grn~F*!XSMolb5kA%pmB zQ4Y4f=^Cjf@A#8EZ<&LQyytBx@!y=3w>##k1yhE55~*R^%eyGgkBg5EtzHIFWDz@7 z56@uG64%?k|5RmlUq|b-+-?bfQk8x;6aSv-W_8p}>eFI@PgX`CLBKyH_Sf(C6kD#w zJlD@ia7g!z9Vl?>x>aVT-v27~yFFyd4;)Q+e`cq)xm&pIJ0Y0=+x6o1x8j?CuO#m; z^e^tl+o0Z?Q=J6Z5Pc?^tlvhrdAGga7EV3$eSf+$+%9C?Ejs1<+^-HNUKTop%?_aNHV+U?Dx&F@<>|F;q0V-4s!a~RG z*u@3EQG+)*_}&l0fR5o3`)WJ~q1%w~Uu7Cpt=Kf`2H(^oHp{|uhQpHf!?cD&X7+u+ zsIW(l5fI!k3QPnW3eJHE6&VQ?JAg}|n59tsztzIqxFR|rkyj2dG8Bv-18adG&bbis zs3^sQhwMz06L+|adX$x8lnpM@jyrNuEpoykG9Lo_x{tU}L+D_lo}(i4529pH067y^ z7C_LbLx>A9aJeinXgH98D}+QHmWBya9tpqO4_8yaM`<_)hpG8(+4${5`0W+@9gs6ic>jY8vkiopD3RXs%%q6ZzL{gBb4nCONP zKX==tC$J>nvRJy&Scb#c9Nf6~j`35tF*H0eVd^oejxiCq5mDR;$Pr{TcVe+RTFePu zhDs?vfC)aB(>!ST(Rjtfc;#rcFy=mGbtL8RAW=&rQO7CqIbOmtciR34TH_GS6&+WH ziF-U6$6p@v5#mqfp&`^GPPQRlp^`Mj;(3n>C!%pBF{R)B<@k?Wb9N~Gg(bcL6@WqL}7SGMg3?O1zH&q7ZMOYMd>;BlklMXw&@0tje%TpIvf{DR~C zEVq*fIQ)zv(u1PqoU%0?q|QOvVvHAg>M$hro@x*Dr46!d&;Krpj1EDr$dSb0;l7cS zr&dVLdunummoNXwX!A>6l>KTd+q9FBs&)1UgWW7(#@?gvhd>}NSh1#>75YZ3fPN#7Eh(42!u}||fK1<&cg&iV7sTak!01eB z^o+Q6)HWh5*VV89HJHQfY!G}7lE<-~;sMG_lYW8{@>1C9csS!o<15))LkjVwrt!HS z5hx)D#RBoTUzAWOyd@HTp2}PrbWZSE6G+fxy)1-d=kcMU2nTvZ+P$EwxMAk3NfdGl z@m;~f`#=)>@Y|uqgiB*0%`k{S3@RHF6Zran>%BJsO#l{f>_60dUZb}F{D*$GX0zh$$1WoK=#Zh?Q}xNiIL(JAKOG32}r z^5gS$26*o-g#xyO2LjtE8tV7F>3as$C-(t!$&8nB5RN$;bz0FmO{OfDhoEsaLU=h{!?66u{A4<}PN(%tBL#;{rQ zJ@k_Gq|^)zNT1gLoi)PuhAMV&{jITl1_scquRPE;!n`lAF1o+&Iu@}r)Cf_Q)eLRy78966}-f`yrCtF|zdaBG-}`JX9Zi-;^;+}c$pcc}nD zzjwL?k@*6(2^N{v-y#yPkTi&w{Idj47P&vI8mHj$|43?gUQQ^ zEuz6>zp2kE%L!T++7Aos%jCp$u{J3;aG&*fct)-0ag~T_IR_unn+oJq1rya zWBSGyr$R&mu}G(bc!g=*` zdi}>5aG_?*Lf{L(Bm>912rQ&(u_*bja&^L4PH5!`hKP4uh@0@D%}Ykx&)&e$(y#u7 zjd^Qx0`d5H``eaSzrLVhx~tBRvQGbAG}CSCJwYH7qsQ*^H{D)){E%*?ed`?j>*XS~ zuB-VEm9W5BnamTrW2fP~o(JYB#A4pU(fP_)YPi zMQVLr$jlJCn;;5=6@SC}zy-eP0*3X96numFKgHIB!GGd2o$7LSp6Tm_Qm(za*4TSjoOfVa0(pA;J?v z14M`w7He_+Gx6}!l+n{cL0UyMvHDVIvmThO{t_z0N{~Q0l(4l z*Vj)nGS(IeNmQsT9yY>8zJra}1E`Fde`gJgDu{g5)8x|r%`vadE>730Ddd*&NQZA+ z0_>?qM(ve*<7_i7-8P|P4|^}DUxs6GHR1eF!hf77l`pw{=5K zKK+4!HQw`>U<9^}ii14I@-#d()}MFhmyB>j^H5sQHZ<%HKxts!SNO>S{t|*?rBNX;2KI zX2l@r24MO#uV61TqSE=i5-bTY3opQ~bvCZT_ID=xGWMmp{k+-(U1_nex!AsPUgJMe z`TAmPvHSY`BaEoZ5~8)#NBg%HrBh{1HNG??{kJX=U1iIqwLE6_w?1>C%3fl8c{1>C zLjh5>qZ%D~rS(G9^iBm7>S;F5YFOngmTmm%M!RvS8Ka$sZ4gj9A7*P^C3O&K#NxS% z{r3-xG{>wb*%KpH?1i$H`&Tv3%*_hp5o{lxWb%l+X44$kM07NdI4Y@MgATLVOQ{OW zpK^|k!rhFpw?amOCLX{GW~yEHnS%I`>*>TmzfJ`s46hmV4J`E0Cz8S+*avMoi7%e@ zcqm~0GRGCL()#4ym2yYf4SXj0)Z5FbAf(D}K}|w1hef!aA?$QB9)g%F&1eP3hLme- zwUXH`lJ~@g@#tv5TJ0J;>kL$AQA{p?R3i=~?`S|cc|R%6R2R!XS}DvD>2IlI+t_gV zQ~YPSr^!lrI$Y&BYNVC0goIx<%+oHhiU=tn)nqK?eGv;+mp{%Q(KGBXt#*&}r23q3 zBJ-4;)r57E)QuZ;?{CK_N2}>Sw32!3z9(r_W}tt>r#}EB`;~F9I-dxF;5)wa<;GVR zoJPvvZlT@NJD}FkU@Ugys)%zZQ-N&ylD}`393?=%&>JBI-C`=M+)ngu`fI0P1_xszq54rer|nt zPM`%co$ET4`NdLawGO%vf3sQ5pUa;d-tgC z{km5e^Vfw?uVx3joj0pDpZMZEq1s(X6nw#r=6XK|TY^p^co}zI`Cmr5fBmis3I57O zA6S~d8WiyJ-8bR1>tDZekDik7OkbSWm$9v0jB!F|&kwE(`a}QBYjxtu2?kGlYyZ(n z2tJH{8f5x1{|lVy;;RT#P@)FoQP0%uH`n~TJd)6*TY=6`Jo5kEd}I90Jb!x;78clz z4Ac5KC5JEW{`>yWJLJc_UzkBg*#7?84lZFO;>u><2qdTcbz%>;)g!@Uyi?9^GkcH;Jn{EF`YH;_mQ2yc2rv1=eWDxeH z_u&QnoGkpa8p|ZaksbvbrV8om5C8Thbn_W(l`8Bh%J&~KP?K9qVkuGzH*EJy#1mW> zV}DQWOiuxIC!tI)ef4*Sj$ypGp)TrR_ST5@;VAXYVDZZ+j$!|IFA<`C2!vXM=Sw7L zN!CVE@p)_1Sq9=UHLB48`D`B+fD31kK#~n3k1wLqE`aVPs3gzuu0;erfLU?GiWZkq z%LkT6es2MX$!8(J6?+a(ldQx&oIW6*%_Tj3KZN&@`*~wwG?k~Lu8(rpj3XPf(_eds z6Ec{C?R}JyVwyQIB{A3>#t) zP1G;K5eWKaKUGilW{7lUMjQW~2C&xLNm%DcCSYrq;zi-Bvx7MFDPdhCu1lRg)W@!3 zgPbsc9PNSrGC)prNWLiQ^laOjY&mfpi}Jqo(G52c`!DIVI)WT0iP0nepfUbYn-%3% zEZrCM?MSkaQz-f0Br<6Hl4vpmG?|3OfjiNfQ$HST_y$~<@`la&n_Y@we~K!NmZP}t zby}?6!A=SY{`^@vr%D^KJ`IJo6Y)|M+BBNTXcVN+nf!dg&K^%#orcgn;L$57qO?d6 zyF>GAsD<2@6yH%izi5jdW3W>#j#b+uzeI>^EhOgjm0zN5ZyN41V?#r+6n%Z1WDRUq zN&XjNSt;dal~Gx_rdcKDSp_uNMN-)%rr93?vN2iN6>Zsa|GQo32+#+d0UpYO{}IP; z7Q{`T_uu+Nju1DB38r@vScuj0QGq&mYA)PlpOAU|L7(X6LvTzjtTt+H?%(-K1%<#6 zp+HE0C^iV0fCOTRVMirqyo-H;m7bZ03(6J%;N*Ys!f_ESDXYdU7p|)LP%DtuP@OE; z()s~d#GBjI-NOZV-=ERW*EyQ^iN9}hs)BoBE_0k`aVc@ScjPPL+tB9L_8{x<{`~6R zchmxV>1ig22Yj9h=83;f#L*?cL>~6wfv^O1o_I2|l=v_JF2UpqFnBDri1S*jCo6LR z%e^dX{YYJj1{kzH*!B|C!^v-$S$Hc8&-((Ql7%{{pU+uoAVxU!EHlTmR62KYM4P1C=tAESxXC`mC9cs2w6@cu zGigfgfB1bNv0-wB=ISV(TYJBju+j@-kIRRALp0*a{stzqfb&W^U75Y6*c5wP>YaRC zvq5`Yvsv30Rjm&?Kb(S&8(Qj{Q+0 zUOn3cFP>$wp^ReGcV6M+9NNa{g<9^UIy}rTAO$R!*&QW)%0HxvzKw>z7a4KleE*y` zdfV8t`4E_InYL_^Da1V1n;q~Z8(s|K!OtrZ&^uzuTe1p-fABQp%`fAF#Q;m*(`s5} zhr|RHRnWz2Fq9qk@^V&2gW53F=&|<04E{6e@{ff_f#tPXq(QvZq{(LR`*Oa^w#NmI z_(vRty#~jeyuy>>`}D_yF~`N9e;n{(PuDP?)UB*Ip1kj2T>eqY!TKVWg`bX8T`sH7>OvPfg z>HAwLzpyAi73`Ni&aV~jW#cmU!r|{Yt;Z%S77`hwsto>J&!R@#h$S~3>}AYToah6R zYN-|JS0)G+9NzdsBQn3+zUBjZo^dKNryh zWQq*|gJBexpU+vT5(Y6UVWjg!2+-vR;&;0w95bCm;mRR9BN5uQg%s`)gV1{ckJukh(c~?X10=H0 zxGX7LTCI^pF?&I*+tsbx+P!DTB?_@vxRCIEnm zz6iZZzmZ(l8o{+7JRXQiChdwu0*C=x_0SDg%x8pZZ6dg2dVq$4M^ji!0VkE+kcLV) zhB#Xf<`(!nXM?azvO`LT!oxfFK)Xz0oJY~O-8=WYMY!y~##G?S@4U;;Wlt|gr$VoP z=L3i^3XuQfN9kacsK%xd(tiq}Xp9QigCAw~=e~$~0`p8_Y$iVNPcbu5xw=~5jCc3% zlIOqR8v56h{1QT$^SpqbR+EFo!qZ3I#20YHl}Uzn2En~%|wtx~z>s5nj~ zn2-KC8^BrfE0{x_PiBW!YbH;*no)?)20I!qGPFsYNufv=sXoE#)eKU{8qkp=fN+sc zm%rElMmT)&tf0KKf*fG$Ihx*2$ej@!asQUk%N2?HJO9!tP?Lkb};+GwLPf`H0` z;MhaWP1~h#=Q(cB`pS8Am|x2+e=-4fj2Nn1LIh_}-kHgx-C|L)p*$}}~RC??)MigtHDT;2F_ z~!m`1IPp_)qbp0>^ zTRe(RRJ_GU7-un==-!?UP48p_HIDsJ}cl+Qc${>1Wisoy^% z_TO%?%g_DQfA1Hy*8bd(cFx#9o-FbF*a}f=`#u@ej^)Vbn{4CwtLI0_wbw5M!t8u0L>!K;f?~O>Q{hdJB3ZA<&q5=9N?vFR|yIuP+ zg8xF$_hP#e0%s5#Mq8^-9>=O-yMtb@rro%FX2qCXC;MLwg_U(|EWW;OHfQuXetmvo zF6Zs=^XcE`lOd&L^tU~4ZqHZjWm*zG{+N#ly87()w7Kr5`}()Fi%~!6%WD3A{V9w) zAM)=`wL~pFKblMYw1WpYlU(2bsbmXb=`n9fGdmFpO|k;l_%h-wnV+jY96y%CxXKS4 z_^k7wsuolGj37yJ3vVE<#|uy=2UT4ODHA3%pzakf5I*)2QfsTsK@H?Xfuh{>%VaPiy} z+=_I>G6Pwe?gLPqJ+EHu7)NoVmYBmiJ&er2Fk+Y2m5!E#KDd(orKJBU4&8K;JU*qz2XPDir)qL(t!E3N3YCG`3wdV@NCOEMmh z0tjHa!omUp002HufC*p&Q1c(1+`SKbuDFu<(-?AIYI^)Okd;to;3r)HVC-Xh9G%*0 z9wEY!rf?P*=79{<$;jkChpQ759`V2g64msHj13R*czE*1r9=XeLa@~AKoFKNBqpZ_ z7Yq=@Dl9GrCGaL!)Pe=DLA4dYJU&QsXB!Wosj~v~ffuW470&#u*p1sP}`zvLEbL($*Jv;X74GuQoV$)dR8IERV z<@^w=9|>jC495L0=H4rd=uazw{bem> zQ_-PN{Bwj$GNS`CK#Fded-Q{Ny{SYQqw66g+#hFB69`yFq|gF(mhBwNU*U`0E<55A zFD&EUb5zoAs^e|oz|s?+K8ZVKjcN6pAE)fel+=24Yq;H@p@YJcZ4n#9 zKtfl)LKbypc#*QI3?P^P!SMy~<2qpgdZ3S_^cge74@;T0HGKCzdfJ;mo3K0&Wbn#) z4TIpjTWkE9r@6PRV-=s8c;M3I3v7$4eY_5b9T@~gJ^bs3kZ5>f$Rp-{J0ttoPXQ=b zB8zHLtAvy&p5Oe8tk*31#%?aj2kD_S8X_^b0?qVm%KL%4$0-}pD^IRJYr1Isx7=>N zQs0TwBhVg~5H!%K`-#tC#^COEzNAtkyY`|v7PlW>nIp!>Nkr6v(mO;1e3*qU#TS_!8Y@+6TTXqVmRX*x@J!!EQ{8-o zTf7UZo^Ye3vo%XGTxA(a^gfUsN*XiT7)sWk&pAplb{4Xt)@ogRrh^POSD+a+{$xaR zHD+c;dyiqyTw*_ttfX>QPOw)h-FZmUMsSv%{>jxFWRU{Av@AL2sG>M zekO+NOV?l8BGKkHQVnmMad z+mk(`3LJNEhMe@;GQqef>1ZfLq-$NdtztJ#2e4O18>&2kt zzG3_3tK{?ZX5Nvb3#y$s)gMD%3rM^D1@E`;Y%CN{eiOKf0~11q^`Ivf%YUK!(_9yLc{kM?RN(fY@^2J8nh=+izN=a#b76KzaM#)I$5SHcT z5ik&!YAfynv~{KE=2aQx`^|LvHYE!l=_4g69k7zSW2)47N|l7Cp<%Ld`hGmm2^5nW ze6DJUKtKpr1qE=(6FFe5Z1+SVXZrJ{v};dO385{V+Fs~wah_@Q+gVF`I6H8vleNiu zsR+)Y09?q5YAa-RHN6=b7-8{UgPC7skUzwQqx~DSfUBp^oSUZ&KgLZKGzD zw$b-q>^`m8O|N2Wo_oR6fz>uH)*S=mpGDb&pD!)~*Ro807<)Tz+`G6e=1T#y$9*nd zZ@Y6JuT{=@JKTG^LeLG-zH~Ydm(^XHaR+o_RbBMGi+4J~Q`kMo!b#-tDF~!V_=?kY zf!vmN-H;W1)qdzaKsmpc_#=Mj@$&Hl4CgvF6zdB#*r&hgliRrur4Y?pk}E4tQ$$HW zKmG@y>Z;qXeU%1Wi!bV*$(_z~M-Zds#Q51xt?#*dl;)(bNXOYzTB5RhH3sxdJ6W!` zvTG=<*+2a3sQYyDl>XJ=;2*W`5J35=h}Lk2lTTzqrieF9q5gmdw|gqnm_KQ1reG&5 zdI(zZJxbik;&0k=t^EU4z6IsymqWrS$}-e3yQ|v*Z?jjOsrgE4DC~_qa(j#i`Es^6 zjsneodc_GoRLB)>ps&|YFg@@mhM$|+C5uewc3xMud_H9_gKhR`U$z)cABW{>!JjFTc^gqA4{bndCr=fM?WEPaK4B^sr>49w zV_uJ4eU3JP+!X6`mFvwjl-C2;qG0fk$06||*I+)f{RTmv)E884-o+vxv9o@3>Tz1? z+;%M=6$X7dcEhSBfKSD{A0<&`81KfZ@=}QXORQ;N+fgd7k2Gm zE4goMt4PVuq8~(BYPimFHMW*-#XCM>Jy(BF6$Zr{UNE>keqJ-OX{Fdc zhra6@e){WK9!+(Hn%n_y{CnqKRruZEN*F4kfzqpC8aQ$YIFU@b>Hj7k6ePGmz}-Bk zlMLX4A0#+4E~vk5&qB><*)kcA*c8QqXx_NJ-Zpw#hoPpn7DW5ZNk56pEseRo3*}%_ zeDnh=|J@b2YBr-?*G=Fb&fM$yHpOYGzfKgAa#aq8OY&$QV;_>zQT0Gh^2VYHMj70f z=@fX~pQeA$q%Kfp1pl=mU|kAeaMePi4ImKHkm(3g71vTn106<7uS5Ya-br_@32Rma zW5~#iM237<4HZKT-C_ok!tfYR{IO%+>Ac4ys|GT|a9P*&cmz~)mct&d!@ewOrV;rO zBQ=f@A-6i=T|D7bs1b8WwJNcQyc9Jqyx<2_wego~UqV!Qk&>da=nWB2%}MznQxth5 zssm4yRm7pP@=?vJnWQNU-&cZ;VBk+p?;Ud zc*Y@ofw&EW2B_`<;Xre4G{f*XC?uE_92*}1)L{oe(&B(yC{l^Q z3y*XxN!TIuEXMZbAyV3b=xJ?dAK8K~M!ee}&<{W=(350qhSjyXN4#Mr5RQ1CMhI?Y zq37E+)bJSX;9?erCJ;jsT@(sbu;4?Ikkzc9M^s;`o5qFjZzCZ0Z zO_=5H=5GZ2((Ejn%+-OzBx8Dbm`j7*ufV8g%)Iie1I=r4A4!7WqGq|l!~r8lmRNzU z>k<~}ymbCKlw~)ExS9C2l@xe(wya^oDN$zRZ5b=-B07%=J1;PosH}0b+&3ldx5W$; zz7K%99oI8rx01pr)H-c9bGMq_!>Dm6oYAQTN=gkrex2Lqw}3v7|FPxy`3=k}!a%uu{JpB?gkF@YslNWs?+EsWgD4K3olK4nIDh{yxWnPHnu zrI~EKz{*6gp9M7{L3(C64Epbm2(636j?410cI=7}t){1SNh>F#&vGYu#pN*7+PZ4; zlwSr71g`eOPYvluy~B-sS*H$!NWaN*=pqSw1IDtsTv-+?2@6Mz2DQFbsm^$AMf$Nl z#Z}>HP_J|K1=lZU#O-QN1N5`8>3RF4HNw$jOT>Y_1r(ew(S4bO>C%(-mqG$bf`#Qg z1f%RX8YT(XTd!4#(W7ocq&k%K5PceV9mgpHv1?llriD!_FZ!VTzNrLIBaLg}@zOm|Vk40H_IQgo;@+O;s%BdJI~apo9# zPM<#*h_9*LX@Oi^<`}^n9E()a>j8pe!z!ymfDR&?x)frNm%+}DIo9ounVX)EHOqU@ z>H(i8K&R1Me<>Um?-1 z`pA95uZ7%(nT!8WA{^i%8q@D^`^j6(uLDFPT_OU>6HS_5J&eV>{&`TkrULCATp9X< zaxA_EY@EKOeT442JPoSjRebsjVe}+?gMLpj@mIuk!0kMl;nYF);3gYuzN9>GN(i0~ z7s5BBS!*6fQa_vH^=kv zP5^Syri4+35ZK@iL(Ue#)iV$bvlK9i^>CzJ34)!&7M*ZjBAjIx!7jSqiAq3#(uMLB z@H&OyMotyw@67nq3F+I0gt0VyMRAV5KZXF67MYNd3O-}uF8wz{0YLmp=vvj3BOsk| zxo#;g7s(W6*Ihz8u|uG%K!k6Thi)yNLJUY9Ik z4sGzH6hc8=H$;<{v49JRDn&FoJ&ldyk@tI;FC7vYDZj(Y4TbLvE>3(FvwX@U5Hcj9 zjLU3}NwjEbp5F3n<1h0?1dS%Z)Y>0-2@!V=qf1O^joAxW-PjO2NwWPS!8)Z2CwtBc zF?-8e6`>^#e?dOh`GbdggtC|gE=r9Jtb?OcSL)k53s+uX+&3lox6N z6O+_MHIO!5de#TL@G{BuJ2zN~$#v}pW31GL_d4o0b7UkWh7ZZADhYe z;u`9J62LMv|7*jzVvF(Ee6RxE4luq8De;=ejWB@vE-G`N9ph@tXI!u1Z$hIIA-Q9$ z_6zJEnIjK3dfV$>n)oW`gY3L5_G+Sf#QQVV*$sNuFU~c{{8#G(2b|<2Da`u@yW15G zzYoLzXrgCl4+Hgi(8>EZh^ihY>Zsfu;zc*9Mqu*t^JhMV0ZJ@Sa?_3-+-cvpHgJNq zXL=5A9Fj#1J_V5(Id$ITzg4u%?9FNSRK6)}%0DLe_Zfpfv^}K)mCRo?k#%&8wWj>+ zx03eu?F~0}soXL+Ioj-Q6-sJMdhyqm$7Rz)QHCSe$=o`bmbBk2$+4>K_vvxeul_RS zs~Uew2hhT=fsQYi4aW{<6XTmh6j|&A+>zE_YK0da2V3*;!wszcokqj&vy-cw$gDoV z9ilL=e~SJBHV;`j`cVj0eJ2Pj2r?)?jOxNX)6vjO+XAnZeTR@_e^e76RSBi9z2~a^ z^s@m_N_+Cv*(Po=w?KM_I7W_?>Jz!LKOfXH&mkAOmPrak-Gu6?e&kNwz0+=K;JyT{%K#OX2Dee z8aU}0QuuNk^u(I?0R|X-y&;yQkH{O53Vqv^eUYkcai%3#ywVbWPpDmc5f3<|-)W4E zv(ETdvo58t4SV0Tpo#nGT2d;sG4|aaE&2l-Onio(&EYsiY>GEBp6&_hoxwepXfOL8 z3tz^+0sYtQV;I01FbGKdUxQ~n0E8F|dGe%X36r8oF{)W2w1EKQS^CJZw zC4dVl$m85Mb9}d{gzJIZiqbbviUwh~_YaJK0^Qh9!XpEs?TivqfeOsvl+;L21`{|w zCjey2R#=>dT2NHsna+e-Q|ppn-JDuQU)~;3PmkIY*~bXT9!xBS1DZxHfa5fi(}5*S zD2ovgI><`k8tulW=QjO#9Buc!+kWznMfdsY^PS9=DzN=0DJ-;BSV-Ij{p`mV zuX|RX62l%j7GUIGJ0Y4V>^Pqt(wY*yFF|JgOcGukVWCCPv(Mwk(ML*@(LdG4+_n9|+ieNh6a#EhA;s-ZKNiZyv2&*_LzgBG{6A z%X6fap{7~dn=vLCZq8FWnOR1$$OPIP)`J2mdttgT*;TpKd`65~29VL0is~dyZQGO5 zfUupaqQtZEqa?OFAC~apj-L#9#&H-&d4gcy8k38t;<2a{8yZpH$!M%Oi0dY$|Ak9Be8X>TRpyX#w%)$*%gp zZCaYSzOiHMDYKU~R~FVdM4Y+*a;QIGV!Nmcshs&%^Uxa4o%Jg(p0()vP5$}7z52}A zAh~Fi7KXoYu9y>H8JxI%fvJ9Y+%vX$Q-P|)ASdBCPj;K zzZL!AFHko?MeKgB%H{RXbd=qHzpp2_pZ?sfxjg-SJZ^gW_vgpe(-Qy-0YH;Qg2=B! zpo$0(=_C>&avh47fIwxo6}ztC4*cw3!h;bqh#8d}c=Qc{)`2!mMuhMg6#8P5ku7l) zc;w5PK#gU8{Bk=HL#J?ctzr2b4)BWv=7@zC+hysVvkfv+w_1Urt9 z1u}MC3K#UHqZ4&?e|ajIb2XkVl~XkBBPUT#2>AxUtqT>(w@q~Lw%A%nec3nt7ntOR zW$?uo6gItto$O0QfkDIEQD=w8p!OTNT$Ck?%W;FM-G_m0O_G_XbwTXJQ9f@QEk}ZS zK{6v`xuboQuG$(Bzhke5*}eWMwg+KOjm*J}sT9%e46&UISMLxNY@DCNFjsw#+3!f- z6m)@+)8n4g`fseBZm(8*yquIzPA6a&x5IQeIteW=&dbqXl_=w*EHb z3*xM%=t2*JB|qlVfF4Cl2|jD^KBMRC=)%I?v5S_UDXK3KJew-p`J+RpY|lGw-Qb+3 zlm(_gmGYh;z8Pw21pZi#Ze-5W(y~L6=&xo+by%4EJvERdRgbs!tTphgl>2_BVewf& zQ4(CMQzA0jXy4I9O?++^$@cLBL0X;ceXaWKkY>bOM@fWIsV2R>^4Lvgi`PAeoD!lT zPkA-*bAPP}r{E?*hL>8^96)KzUT^h{c2m?}N5>aD2Je%IQLvP3jTQ0?<|~(59Gs*L zZhiIE!&W+{o*F9k`Qo-FxxBhaPdJUlXI7WViCevu&OGk#46-=A5p#*BKD+u~)cw{f zW+Pc@C&?*mX{{+xxWtI(v?MTY1nH>%$h{0f%9#KYm$m(<*3spBk^d zx2n@|l3By%!nzAqNE=y7Y=-fYfzp+@nS#c6?3?6FLPhR7^T@+lnDN@lY~YM^J>~C= zwfAc?Eg4nH4)jLguZS7x6XR|H%hg6-kkA521?WP8uEVL|kEOKrv$$|`g&Fz% zR#8)1`Op|OyLBPHSXR|>m-?R|p(MlU_p?31-lo$6?cYN~b+H*99Nkpj7!}^;hrIpW zFe$R@VU2+vFCs>$4{}?TK}dIwtDiIz#6^KqmeTCxM8A*wrSQ|StlG&4(LoHV?h6yTe(9J2}Bri(Y37(is_oxWEgtroP(Lh_5WQ?`2m*>@L$j)9^eS5 z2Soj^K@TyLP*)f%d6MBq70@3gUGZLyr5_M^^4`CC8VZW=QRK>>0EP>IVW{)hK07;# z_*hrnMI1ui7-s%qRuE4{l<-&!6lMSl|1j>M>Ak$XRujsl}6XSs=3`oI)u$%URn0rTB&@#-ai8hZrrrd4i^2X zvNlX#A-(}DKq4Uikg%Z56N53bTQ-u_@t#eUBV8R;2=!VNi=$@Gm=hZyQL8Igc^HvS zrld{e#%&s#Ywm148Jjq!P)rb#)DmM}3{#=Kj1{$%VTDxg7UYHIiPh%hF!>lW+FP^7 zCKE8{3?eC^6Cg;73DSp{cG|)0%Ipz3TZHoVuK?^nv&^im`M`J@N-tArpeu?}J6r#bn$M>P}N9$!S4cquDlOFPULzglMeg-4=GPixX zk1pV)yA#2w{a6|do35sPP9r;_&A8~vfhREN+tFpQY`#2*mW%W`hc?8fB*aEq#pL4$tcd;9b5amWB7Bl3%5=J~htp_P8TVLWci`!`dB)Vpe8yG| zlNqQutuc`yKYFSPC^98Bp@V1YGe2jyiA1;=(kH;lLeF7=iDq-7_ndqw$K10S( z*Ka_%K`;OD-iiKY69^S;3I`viCxTm#QkUWi%Ke?u1@eTo0_^9(7ghg&_AY$!10?{2 zhVD~Bi=2Q*bGT2U-~OsKr>_!ir97D|xtXEKF5pDxRS9o`d{UN#jFZ6X`I@W$Ca6P+ zR0y|q1en`+<|WEn-hOef!p!wK@dC@3odS@WMP*-Rn;oMrz+R4;Q1eIKN&*;PuRsLBv9J2r_Svr z_Z3jI#(8m(zzNb^o2M%vv)_ z+B}iTE5@`&R!704tvu!AwG_275fvY__2LrB_om5SX38)(x@jq8nCCX1yv52n<4ZYP zrs71_dJMRs5KJ#q=1Q}0V_+Jt(WSTiv*Z=w#8(;m_^E+TujaLSt9h2D1}T`8Ra9ms zrASndajZj{Uob6Wf!B&cO;}DVEG;t|tDIaxZc?;&QL8L0lMZ}1?JBIEKC)L%p+Tl7 zhOMDJMtR6(u`#1zY@HCpVd0zwmet%y%_e3!5C}zoXQuC#`njHd4nn4E(ukK&E_)yx zD>tE|d>ikGwJ(HArsC8JEnHbTd|9)h>~PkSHD`Fp_lWtEWWpl299%WZ`u>u-T9l?ED89!e2GF)jU1~*%7_r~P{_xE-p7s9GZ z+8$ZIEvtcIak{q?56$~Xq{m+i8(`PEtzAyy^~_Zs zU{(9ZrZsdF8%Ld3r%H^eH4gEr;%Q*B#Ld@wR^_PJLOszRIwNTL7f~;e>Cii?Dv7P@ zP=1D0C#RwiL##N{26|SMGmF=lI=gSE1p|$x*0nloL9q(H=t{4zM-mEwF{HDqjS}yF zYbN8>o7iRo`eX7#V0)|N6l&7L@2mG3feEB7%XU1XGw=j-=p^CHL&*|ETHsf$~3?O&I_WKpw#7f9ZhtjtmzU;~-C# z8VPwWfDH|&b_jX zp@l|6(dfZGF@6x;XLZ;J8kF=<6k2dj2BmE(Hev{G(0kjrZ#BRPf==RKejOJZQDfAVgr<4T_N!Gk^EX=JSxo9TABso1ZD^VgmlPF|N*by(EkirQ^ z&(QHOf%pWHgPt!!4f~}U$D!O1>mr}VlqT3sKysDPAphSld#3Z8mdDxUa#z7)@ecp> zEVp<77gx`_83x8w?eH~1HT>)QtrCu?Uim9><9OKlVvaP>Lb_JVJ!%A(GaT+W{2e?Q z@!A4_t#ya?kx4Q6AVK>cyvjhpJ&(o1lRHF@5nM^xdtp`EKQ&tzBGT=YIch*bli1U4 z-PV4QwJQSj9zJcVn;85jotw{=Z9-U{tTn<)`GDi-Q*EpiDjwWSMNJ>O$+UOD5B|3tal8c zOr`K=HC*_16pH+@nGZaPna+!0)tc_TfQ(OBknl~Hh3{+ocMxv^pKNn~!b=^q;5J6z zFKMT_W!b7U)UZ-_?s4dF0yAWTHe1NAhCYY>pEh0ALrqtOCi}z6o;v}5Hf;fDI`(S{ zRmA%+ar};&!|Yc^mNIW?9*K~O)}poLdHf_l88V3(m@3ik>wnCVDYD5gL1Mv37Loh) z9`Rb5K(VxVTD;8!QoyqPw}$RF-`NrpjU*i!k*nlVwME9w%gTzVnCHzGfa;kifhy&l zk8P2q@)upf-V4nw`m)Aait zH|8zuOaU3LfPom)5F3H(_q=GBUQjU}%5|O>)p)pNp>x2?Qppe?vB`6qGcQYBJtkee zqWe_OKg7*6N7wny49^6|?JWPA&0Qc99YY%xyz|MY`>DGxGlvd_89$ve6zYs?X2!o}XA;__xWy;gZ?2YV6gXPH4BZ`k0B239;Akoq zo^*!(J*)|K|83$8dIS=St72Ys z&Q{eRql`V$RG7>|2f4-&*V6-NrX)?c z2y?{VSJIV`Nnj4UD_0R&u#KU~KgJRy=9X7-2rQ`TnVKb~h3oH6 zQ~kng?mt*+%LWRJ2|)Gne6D$cOvKh@c`M?Plggkwp>SE7Xo#up^IO@v^j8kSkYZ4# zLCJ8S$CrziyuT9PlH zs8?$hQdj6}vcD}S&15^s`@{||wW@f-n5*T4)-Kmj1m05PknW|l^b4WTzBFoeoBKDm zxpJY^8OfN$u&(i4bJ&jRYOGKEN_#RCdjY(yb8VjFd(m4~KXjur@A)^#x!?ux>vEA% z`n;(h$I*Nq8hz6CFHhT*WN(|S06ih+=Nrk9`2i8Oo4M)Wi3cOS_pamf{tM%(1}`5v z7X(zfodQKKZni4)On$#^@ml_vI}>F>CFH+&UsbgbRrJR9_gKfo)|2_2ZS%bU(joI# zFj^Xqswj5SHJtWa>`N8Pl^7oMpgG(1Io~|p{bF!>3jQ!3RH}4{!6;{F4^nRFgCFRAs0p~mrm6PwTgMMaU%sxJdv*8I zrXrD?{Pb=7NBNVAG;*<;#;}`do1)NjJG_=am_L527Yio-Q@&mI)KFG#^(kY<#~`3n zeysXdc}Kew1!pCL^3+)Rk;oJL2I=S{I5Bn#IvhpL^Jj?RsgT_~>_}4<9w~2(Rx&~NVdh25uc1$p!OR}- zTD?&<7L5kRIZ3JKKsa44?gA6ud>>x3KeqXDMPu z2`b)kDdgn)qVd~MU^kkP>uzs@@uFzTw`rhjSBE~R>uFu=)t9@)9G3>+{Z1|FABXnE zIDTjEUtt%XHZ;BQ{%R6!-1)W8h3n;c`_*O7m$$gozB?nBP5g%+47grhMX$~KT{Y4e z1#Fco1piT7czM-#S-sF0co(eV;(fns@>cI5_tjP4udVcA=p~WVfzG!N;f2 zF=_-NIx&K4?GD$R5YKZwysw+NS=N&=19(g5 zI|OKPpd~s!juu=dcQvL}*GSg&Aq;g>GvX8kDm(0BN_;cM|Hx`Um--K9Spf)rjsgt- z=gyJ}MY{1y#Pmk25S{ekr!H6$Fytsw94Z-O>Z4x_kvM7YH%5t)INRZTiDHg}u;-#k z%9rR0%*=zl=gXs?%m!1s2N|OKZF- zcmFyQ%*VWKXyCJ35KZ`lp<(6DebdA#xX943%Zh1V(D84>B}(7!qPXL2P{E_a*U-Z7 zoHCIsEo}M<515|uT=_M+EMf8!)C$Xjn9q6x9SE&QWU<@*(ZVE~RIV@N=hqBR?epRZ&YMp^l(zTXB z4Tb2$v{GgFCn)Id*JX&7SDD;)vfj3x%&er8*^tn72KjkrbJ72d>vH*kvEV@C z4QhMGj>Ff$Iy>De2L9-`Uds(-4v>S zJx3pvIPM^-$BH-eOe!{>Te=?_#J6ppOTdmZ|A3gSy1FEGLhSp7y&zXX=j|O)zm;C@ zczF~QtP3=48!iS0ew!8FBMM1;c_f~0)V+a4Qv^IAjG6D=s=T7=IkvmyxcuC7O!fOy z+rrc@p(0&ney%SB zAh1p;s##_@imPd2Si)93qq3*6jDA?NL2~w)>MQ&= z<);JHMmwSB1l8!E^Dn-SI-%5PVOz>njuXkHAKb7}^4dt<3g5(|Kj9-K;S02#%qL7c z&qNOMnfUL3H~2X~bCK}pqRGq1l(4B#N*DRrQ{@ARgf{}Kl6tNu6WLNuw1wAg)~cC8 z#pIqn#7uIzP+Rln*cI03LL2d$0)3^^kvalx8LJIXNtIe>6*^h6mk#>X`tP!4F*EEY z0)oFm-jMU{&n8Ai`YCdl<8fp4`VdRHCX5`-6Xvm6bV`qMj*G z+o7IK8RsxphpTdlUQbtj?9NXiJGrHk>GCWX^_boH!Pxw=B4@bP<)4B+yO@UXaNXtF)rOZN7d$qE6!JWR^x#i>kF)7TXZL-fgx^}Gb7Y@#d|X>F2hazsaHv1+S;ilfC4E3=h!%c-tz z%1cAb zwKprf)MJBG-Q?MW>u~()w6cfuSZmv+YuC$*_XO%^D|*bQnOkSr>R76s)%DIxR+;px z8cL4H8d^U6%B!zDu9askadD<#?_C-8Z)kfK64dM=z0135B0@E=>)Ur{Z|dsk+&HNN zY2;%Pv1{)r4)?n_7=~Uh0cG0Nz#&B`vJ(Wsd(~yqRK5!OA@(VJ>@CR4(w5 z*o~S_M9O(kyUgylp@$gm*UgT`Ktf*r2DZzu{CrUc1rP;BMWZk#%5;`w`i#R~V&PK~ zzOiqJz?b#;>p6mx<@B&&Th;Ke>DYDgu*LqLD5eXL1keOX{LePHPK4Rl#~~^omlKMj zD;XYQP)xadE*25byGo+n2)e47+Uk%(d)5#K9WsD!>HZ;~r7bn|S||X)ue-V2B^uPd z$?gM1@ec^11;|U28Oo8!JE+Ph$)%8@%3IUKXj0~wDpBg>668ZmfmP6&x`rkM zMJc?wy}G!dyRo;vzlO4lyn}FrY^=O(v?p(7a&EeBc3^w~HdVVux-qf7g#KlFXLyU` z^AYjMr^OZOz2lwhvzt?*jl=V=m%9&y-#%1>w|K6MUkC0#690LZgm{Y%u=tsFf@LNe ziAyMjYR$ec6H53btj%9hqRFE|Ca=ZQ13W}~iz0_EONSg*L4sbhkzQ`-bcgO~mUy@`b{Z03Nv!SQwOJPL-bR2+;K!h~Bk>?U^NhpUAW*?jMZ_HJ)91WGw;#9s=hL*ubT1#=EI`xDy1wCv$B z>ZJO94$u&i0HSyANtJbJqhWDG!LXE24_GE$PVBq<#6oBwL0SnkD@rZ5G9ih$s2-8g zRMuJ%Pf#FSo7ziKnmtI8*HKf4-q6=fQ$Eu^R6Vk=G|@j5vx-C?P97~z|NM!1g?M(o z)BmXFgm|*Wo7A^z=l*698p)=qwgyC|(z+ro(^H}`DTRSc-Jyj0&~!`fB#zT;wOmv- zs+)nt7<>j~NIVhF1Xtw zq3H_p<~#6I$Z`>F_heqT*ve=Y8gYNFcC=mB5;1`Jo6d_EHnKAl$w$MLr8~UWoJDAw z#BO$J(wAxTnuN-?t$qE2a*OhgAMZJy*LYlhUElNGjgV6Gw3XTAtH%Yu*t3^Ww!@JT zVbhv@Km948P#^`%o&KF%`kRnR(ZRNX-#@PRXNpxm{QCp_uVpX^C;;#RnEs!Z!3m^Z z%&ete3&{Y73sHA}Og)a4qrH}d0_bQ;kPN7xG>|#c5(lsUxHT3Ug%vdo%!9*I2mxVm zbRTBZRB=_ZlsVhjyh11z8|eA?BJv{eA@X+$CJJ?rAdIrIiFJq%34?ohdS}>W1tt(C zg%?B@`5}UG=+ayx)B~zS%L(gf)q$WssZy!FKBy)7o8Eq1dN7KqX)D3ZY-#i?M3Z%G zeS>;>c^-Yy^rO}CDqRn9pi>4poH~3mN!v(}kKRIL-JY9W5n1SqP84ar!u|1se1LP} z=5a~UkOlzEmZADBe8dLrEhCXm3oSzeo;d!E0Za65P73)}f5}91cp97Xq-=@$p?ns= z03%25bVw$ZiZFo4m#=&>m7K$eAq>caf$gMPCSNGuQM*z{^`A7BB|s?v4j_NFss+!K zT-|`sx4FJ2Qpsq13 zIMKvxuNtPSw=XazN9D>;_nGA=L79#n%xibw&uKH_4)+X{LPEpBBO;?B@&9W!Hvu)z z!Z29R{bK(|zmL-Y^~bZi008*h0H`3I|6hLo0%!oBJ~sd=ln0m+H=zCTKUV7spc+8( zJVF4f3C|QOs23JHH6%3A?3VsLR1AbVVhTkOrjigs6??%{!V#Jg=1g)6WQ6QC+K6Uk zNYO0BM*NFwwV)I3m+#nS%tGzF8K-POq?m@9n*88A1d?H?6P~1`Y4O59frS5I)4Aul zWcu%OIr41NAv__6*MPsK#BfWyB1`+}cs4aIkK-u?dX6 zNl66;foMY6Q0bZI1xqERUJwF&xfhlAA;j^t;3<|btf5P!6bCS>m;W)Y(dV5n^ndMq z2hefCT;CO%X`*E=rEG1ZV;zpQVyUweeN?@I7&+c61#vB?F%D#e$pen1E@ojBLywnJ zAes7nn=JJ)?j<-KZ=BWDhoHG*D$P3sjfDv7RG@;h8RefT*a=AL%IE9n2DPH+2fv1T zknr34IVF(TK$BG&Gh*X%G*}B#i(+E488s`?h>H=m4D~6EhSgc|b>$sZCJ6La`u4); z4=ufI{bPyU4#N^NmE)NUQzIWc37c!ymhuOdk&9(Jv+46@2SlTv<|aOuo^K4UoP9ZL zxZi)gJ-R&EIZS(5QYeVN4Y~Z~eJv%z`VHeFVRQl_!VB#|i=(6_LpmCy)eyLhDizuA zRz>0qg=$qEg2-AEig#TZ`8q}bv^*PwH>X5z>)uRZDkhf3NIoA~VjdD3#UM|f6mlnt z8~V~9u(mOjt*c))6pSELqkaok06QVNl8W{*8!kSQaAj`Gc`f0kmySp3d7D*)p>5`T%AG*7{ySux)6p)hc5lcddDM4N&LhB@+_+(8|%F2tVRW}bo}&e8G4 zN&4yGxn7(_y05c54GaBWm}U@1HoI5)3a56L4#$qew%5)#ijR(0Y1j9c?|(j?+G4JcE}cl?BS-|SzuC1`C}`p6}enVNqt_K6V|&^;LI6ArX|4Nvzn)oi<{7k z@zHIdVsyjYDCcFup_|U;w=C{|31m=_Sa|Wb`p+ zifEvMmmv4pa{?^vKF9zrePT&ljiR?$h~I(pvB84EkwL{S33^1xi|WRG$Y!a~lx=Q+V9o(7&1+Y|DC@{i%l}w;#fh&Y-gCzEiA*hwT~q0&t|S9*G;ZXQNW>4OHz68-$^l_oWg4a` zOoDb0ZS$o-ElIC#&n08MOc`w#-i~GqjTYzEJ>4V({p;nffqG;Se3w&w1_+;{@lqx> zn|+^cWc!+#zg3c;Ef(7nI2-qRVd;~eGINJrI|4#!wCj3DV0qo8g(CD>1I@bvw)s_acMC=zaO`;R3e;&%MgR^)I3bY2pP5=4P@*2V7o-Q0z!!&YBj9lgYDjKa9l znC&KL{ODqqk#ZE+n+xC;tJimMRIgX0=%YFX>6 zfO0n6sW5OF3AsdDJ98&51*jjECWD#4-a~5W_6&*Vb9;Eycco zdv%YiPtSNRM78?rmqY+3XU0~c5F-}-zj}nCbevF0uN3lMI%E0U5V+ck!anc_5|nm#vx4lRY~!+X5Fcbx)FP&i}cc2*d`5WM1>_%sSLq2lr}Y# z3$ZWIly4${x}iu+`?~1(hJLP$sl@HiJzwQiwd|-D>m*+IO3b_b46=w8ruTW0hc8EA zU4yl|IB%8qEBR|=>j*bnZX$4gK!;6p$ni;2t_-?j*d%_nw{Yzbr4S_EuKyZ4D2)1G zQRCQAu@_Rw)b#67&*%)ParA48yS~)L$Ij(j)vHWpNBhCZ4|kFGKX>QiHBH&Nc?y0a zPkk$KMagb7URl<4mlxA>_4u}Hpq#3l9qKGJnn?HNjrX6uUwYNM?>_iFxGlQU4SiU! zJUEw6_2WX+`SAJd55Wf0Lp<=PFO-yh5Xp=H8i$5DTxt$D8(4_}7guctPaZjy zmU)s)ZI4Sb#tMTkgVSjM88SxrCdvg~SO95J@kj`XSAm20!@m631x7?+8wYUUNleGV z$92JkXz}WS0fOi0W(hwbO8$wFdh?Nm_-%yNcpwj?w3JjmAYC!j*ccG0C`C8`DWM7L zUmURlKrq1PWv=pH!`WohpnraIT5D99l9yDf3ZeezH}|kd7(IQKP?XGLA&za6U>>v8 zKn51M*qjN~zG8HptY)jj3!u zf?v7vyp2F2MFb`$f?%m&gmeT5GzY;g_LVIU>=P7Hj*tNcr;>q^KnUT?0B>`{0`bsx zUQjc>UJq}7Cu`IYV$7QfzM#>unP@z~_{`iq^YX+8F9G$Wb@^|rguAlI2?4y8*xly{ zL4cc^oE%7HHF$ad0DoD}dgsgW>uy`f%6J_&Jhq+y4dIV|JgWrGdmdK$wwLe@5&eCp zS1nr^TIKQJ=HMt-#hK#A~Tu z2#DuqQlnvvE@8=)DxUjfqg^6HXTQ(Php3%rlpR6Fl3)3)R%$T7Or(J|t}%MS!eDag z+@S5^^Ki*s!nlBkVe?Hh} z821Au$mjX2&ZYYM&PmFUYN49|sQjLf8OT3RIK3r?JJ7Wm`kedUrH1{Ex5`tZI!Io3 zoWwgc^dcQNqWVN{ag`1 z|3(|hfGo5VK==0Be)0$GaU)(lL&y9GIp=bkbf$oI>HxzLYl}2hJt93ckWpJPj?(#k zWUkghx;gT)D6Mf6?o67$BDOKDg$oXGvIUf<9h^Z+_8LCI^t-HJE`3xhNs$>!7SzvX zr;?|pl;WW_POA~ufg-#$wj+rkI2HJjs3qc>g=mTvvy8i6oST(k4y%qe053vMI6C`l zm!4dy+_$7i>@_0CXhERP&V+cSf)|eQt7%FJ@rO3&@T!Elj0E7ys&kxArrbw;ZH{%4 zXenP?yfCzJo5TxkhbJC{SNvOF(x6MKr;#EU`hfDGnJ@Z3I0+v$Y=^(Py@$0@);d;= z$z7>&>H{#hl#u@6h}FC}QvT~%W&l0|q5ww!eU>XA?wJ38S|W6r`0AGqhs_aD;pJJ@ zymUAaFu+!UwE>wo*Li#oiat_?>t>}_`!>*V;#>)~QkTZC;x#*T;xR4vLfw2vHCGdv z|3h@7j->2Hmc&H}2oJ#q2%Cp$*a&(=ImPgU;x&x~9a3;f5WuVV0zjD?KX^zTx+M692vWVy z7xzs%d`BPy4{{_3+4ny`##_7Qzq~s5wT%1q`tIH^Yb|suw*Dj3WSUxSaYr_TJ@yF;h{Q>xqcZ_ACG14F8`M{@3evZH9!CHcDY`t_Wtw={VDV&VoEZ$)zHu#ceN%P!TvM3^}~sD zP3Ek4_pgVin;)T@&u-UD2L>*nRrxJ6UDwnY+shwrgnpbyhveF;_wVwoF#KBeJ#hZM zGloyx5>N!r#v>YrFs#l|dLo#-+kq1o2!4oqoGvqpW-kfb4gLW?A_(Tt(V=j%#X1g% zN1|p*NnqnFFHC$ZIUbP2lEJtcQvSzd&zBm%d?%FE-n!7Aj9QQ`?fvF~d7^F3cs^QI zb-PilKnas+3U3RdR*s8QSbhps%dt@&xg4XJlQFwcNr5>&vt_E+!PsGpAN3Wrx5MiA zZmtz|#X+$av-v)LFH((-=q4vddY;&)oagK?aDI?dXY4kN9<|V-u+xZ4VIylLKWqD8+$IvA)KhV|- zp7{7XWnJef`*$ws=V0HB zyvjf%e|~?ZSIg!J%ut8AIfQYD4+>Yn#@VvPvF=sFyYGgyX-x+2IQbi257K}KfkD|! zk~?WnMB|RF^G@IJDBu4kX4SaY4=8R8+BhtT-gp>^q$fo3a@F*4F&De0r(ZpY1?Cfy4kF zArKhq6~qBRuoZTSPC`Nu21O-HLqY|BnMpbPYWW&|Lhnn60M#*aa|19lbt*i zfH5`y5IDcc`qkBdef!8~zwhmjOew4jMO(lWtdo@r{>fjpHd<#)5iEeNcIQ4z*Z>}S z4xxLvtxQdbz}FOA-=2KeVmuf@CBkoHLQW_QDzn*U?k_-(S15L=$CeCzEBP?LsE$nD znyoR#MtZ_IN>Iu-qF4;%t6-~;tExbS)seitRSTSkuae&oAz3dg&#b@NY_B)O5C z_#6DS7DLWVpLM4*K*vlarrtHAZNIFRi;Y=w$X0*bF|~(!=bwx8|6m+9=io4W^o&31 z4F7G<-Y<-GR_2Mae?cl}zrAp3e|X`Gct>1*tY*1kIObim15V(GrJ43Eyniig`0UH^ zMDQJRipY}O`N&*g!)qGrD8L^`O{rsw-6E0iwp-sy>4FwAn(qhp^Dqdz()QRkB5J7H z4kVMa+Hq&x5h#F@{|X(6JQ*&_i;4S+xD}0mvAlyUsv2+P%G1HH=P$*o_#yF^Sb0Ib z7QPi-JjM&PcsI74tk$HLK)d3iU(xutzK(|zQ=Fh_DJ zJtyI3_%Cy0;{e!pE`J+SS)ebz?oQUBScXNBL4#`Xww4(dyY9w= z@{7hZxl{Ju4vpbcXpbBcYvh290&CkZ`$vaX;H)cM7mmDBT7wIg3R{m?KfbEWlnLsK zd*g=Vhy^0!ZDoB3e^ikP={)C5XHyO<^eulOB_}U?EoM*>*Y4KO8I{*{+7jbWyf_M! zXq+0#^mKOD47A;lM3vDXz&N@WE@!+L6hj+V0`*7KuTfY&pX4-deRr%X0ie!Bl=cw? zbAzaFddAPD5vK_Pt$P}sp5E{s#bFQP;uq)!m`bR8)tTBD`ywMI;lcS$=C2^=6>5$o zkSD$;>m1M0yd6 z_aZi6{JTX7e^Hmz{99e}vF|@~ciQr7tBRT`JyJRN)c+(SFG^I1#76~IVkRiiVf-bZ z`1@ZeROU$9@=rPvsR_XQ}&wZ$8A2XZfn)S?S5}6zduWx`viVMfQPc^ z21Qx{HN#$Zu_8bOXl%SRDT0!)UwU4)phliC#6l2SobD-PRA~$-;0M2Wv_nA6A~Uec2rWN47^+X|!U!+{$)elIGzGAjMspB8b9xok z*DH<2^MJ}s!Zb|BUycU|OD!zyPf~N~`(@ny7_E2tJvH2JO?#N~>9-I0uCA#$3*)7l zqg6??ez%uU*iMjCY!0`DmQWeMC~2e#VvdEVL&Q?KL}mUlS}_t1?hUeC+wnkg*UD^? zaBhxoP34Ge3%q;?G^t12CJDiKv|GF~{r1L$d@U*p{5^WPPRuW?wf@GO!zZqg4?0_H6kjBHCW}Zv1 zpkbLuI#O2bYFeX4pY3_Uzwh@Mz2Y!6MJdCg*vD{{J`YhvsXRY^DfK8mQh51DN2tTi zsw}Z4W1z4mg}I_iqnUZVvUQ}qphjdu(JY_OY=x=7+pX+4yC{J9=()bme$}?5guaq7 zUquz=ym3Nq(zd?V*}FR1&t|QaYjcV`U`XVHew!bY>OvgxP8p*9`S+U27{D@cDPdX-O#_hZ~>*h=E-hSoj z6F$irlpTA$^$COP9i8UApvaeVkJnYPdjej3{$w0V%({I^((RVG_mGAg_LD=RjZo-C zB6=^P0z+1ShT)ast1&%OGRhA8M@~8yvzzL|ST$=x$1Y?@Rt&Pn8D(QT4+U-CqRInT zY@ZUPn&HD6MgQ-ws1s6tbQco{aAvvNzYDw_hXD#EGs{8*BzAQ;5LR%KA%u5W%8ZzV znTV70SIs3X5s+7Q7fp@FRLAr=~A353*UA-q+6P&+|HjXg&&^`0?7*>7oF zM47PYI3q0ZKsX+CJ%hyE7B+`kz<-Rzd=y`HXa6-4hXY>Nj(~vw>&`wRjbTc@EF!IQ ztSVvxoB;a&Oblm({Lg$YpZi`k39K-~)|c+A3)f}%<#rDp3~{>3&07dku~nC51$UaY zS~HrmZv+Q7`Pc&`Htu|IRWB!(z5D|teEdRm5dtG35npciC;>i1C3%74(sv2+q)g9E8dlSYRQM{m$ud*CxV;o4<1b|LX0%nk^c`77R z$1I_VuNsssW;W*)$zb2QSV3%HFzlZ$4l*?nE&ONhr5Xi06Rt>v5#v0qT>3Sk@EaS9(l>T8&3ds?iqtT)7{nkx zmgs7`sc^O(O(|`g5+k48Lky!nSIFRqtxXEjDj9H~rEhX(qtoL13Fh5oVQNr!o1vo4 zL~AYf$iNws=i@FRP{V~WwYkf`{(wH~R&mUo&n0fYh$pRNFe8*_1b06y#@F;0sVy7M zkc!e7pF_2zs-^K$K;kuhXKe24%~JjVAVBawoZTSgQmEYB2xF%V)V*dze1=JP7@|hvzHKrE#-#4&-2KRfHW}Th9h~kQHEh$EK|qOo#;@- zve?|w#Nqa}1xFEHtL52aQK!Qb^f(nwL&P^3iy>MT#^zyiHtpuAuYJB1`m0kb(&Jd* zr<;G&S7q7@msujD&oZ4MGR@X05GqLe$Ua|^?VyTRnk6ARN}sE`8pe?4#Xf$7{-(r< zGR~iw%PLpxZ@ER0_RE*Tkdbt2>`ZufJ@Rbh?rX@1Kp{A2O3 zX9QE(i{(!hyEXdhiPy-4p6+wyD@JCk#tw0m;|73+{!vW{wth*AA30Jr#)1v9ed&%N z$$90WUIuGS_tI5mV^aZvgZw!x^P+UcZ)G#N!u}&$?MJuV*&z3nK6fqln@+BLvR4mI82be$oCK+I>z6Sc zpHA3^XbVUKCy*Mue#VI*kn&U#E>_i#A#zNgx2cA*ZjH6$Z=BD&(7$e2(pvj<^Hp7+ zwXp$edFr~Pff2<&W+QFzWA?Gfz;)ehwz_uIEz-_4(EP>id&c^aMPSr|N38L?2e{_< zpeqh~>$WEi``x#M@2}gRcT+B-J?GdmJAc&+_M!+cd&j8O&IkYW5u6Htv%$NY`5}z& zSbxvQ>r|olqVX`|cenI(>tyT+Ev1)5WD^ZTs~F8+(MrIpyK%sKxc8?t#6r-az}@aY^;$LixXahXh#R(ENgivr?h+rdeS# zWI!V*$6rGY8Sz*)ETEA|eKAU93P?;BF-!_!Ky#G^eA*2TMxK00U>{?cor1N$qKYY6 zQhYp9S|R1Bg1m_6Ru-G?A@Zf5v9O7bGzq>W)oLYNbU|`lasbTb91bM+o|D6Na-!yq zLqSN5AH!j%O^EX-gzPuU@sKma<0a>alRX$~tE6I&(swbNbd-yAwv$G&Lh;nXDXVm$ z(cNDFSh3bP>vTMyr<#!2a+${YYwp06d%G&2FTrUKvQ@Ej*3Qg=yZVAD(- z_9ct4ZDy8?VvccmD=)Wux-3z4tfLYCmGM0QR)F~zTH=54_$f-CPzdG!Wc-?PC){EB z|LlmgQ9(QZlktgT6^tYt0ek;kYim)~t6j0>p3Cy;H6k*~W6PX<3#6K|_eK$G@)1Am zxb)DYlDK@FMDPp<#Bux_8m8bM6lDkS36D>Zh>T9rG)v5g2Xdw63L#_`hJ#e|%6MWG z-a|{v4ap!d#pJqHyaGAk$2NOFQ)g{YE5J#nWXPjKwtJ!uDmOmsJ|zwN!bdikCY$}u zqhA`hzJ(1Cp`r!D&cPHfNuQH*ZU6AahvC2-AU8vLHqSzdu?Y`6$3{>4Jp!QR0p7`w zZeMIkQ{~(>j}z?WjRw&?Q%CR)?vdj;6$L@&JVGUusDY?yQ}AnZOk379nMNV>Jeag- z=-K4>$OpB29=bCj<|HeUl4ahifYo^>k_stDJ)Vy@aqon zoRX+*PFxWOg;;d06-#xN4%6A=JMG^SI}PCJ+I*EoZ|zZsv}7(MVH48rEKZ-ybUNM8 z4`CtlfAc~jLnsgtirx>*L*dd+xy?I%RiU5iZ!o8oY#L!S0{(mEv0qEX_Z&}o8GGx# zI_f(sBA$OCNeiHS#%%45C;7~u#4rZG;W`4-JcNgCL6Hx(DM287;I==`j2aa=frY|Q zh>XGt6_jEV%Oq^U$)f7G)?7SWddexM2!_wVm;hjrr@89)8xvnB9-AfnB$CK>eAv*A}3qJtyGE@xI5mk20EYFcl12xwuEUn_H z$T#)K43iBRybN|fF?xu|uA69np4Il>t9Cnl{evCN*QbZV%3F)gL1wvV8oBm!`BiAP z<0@zEpCA492-CN7SNH~J^IHRUwd(?l**srG+_MGNG%$Kxw>?s;TU&i{PX+qn(qf|3A|ibSz7b}US#2nMthw3UH~D-0y#PVg3ohLGv3a>L(BNUM zw9=q+UvO8o?IJ`Z=5Dj8;W+Z zE4t=HeE;^YN6Q-156^b%!HN+|ioA`>p7g;#2eaep-iUaFXd8(E5Jdwq0w{h95&e6e z>i!Iu0R(de02!Ks!^85p$hQkbTYe-`JOC&a%}|i2xx=}rt*|4hqHsrzfda7Mn5S|S zP=u*W72sOT6>C<1zxXxj*yzzsmwKKNZIm;j1g zCG4ZsY`}h%&dCUZZ@l@UI^V5 zZ>j7P3cs$zmjdG3GD{yxx!iy6W*q<~fSnfykN+z#uP2G*|39Fpp;32q{0C4t^ifg% zFQ6a}_m>1ZeiY7C(|;k)y_A#C1XP8h#_Tz}RX_-{_`nE|MoD%`MAisWhDFYrKH5BHqSAFz<2T}C;AWq}a8cD$UDS*^+xDxYlSumy4 z)?{n!0;U`A`F9*n!Z>9&=r>{zVc)fhbObgHDBUA3H<9avd6*W&X_l77*ARek&|ea;G8~E}t==UFhvv~@w2d)DwY>e&q z&0>gn_Ep^?P;}+E8y$4{iKI^9&qWxf;3MH8ITYxKC`cM4px`lPC$0sKp(QpM%ZHH@ zH!KSSq6ihk8J6M-s0P9jF~V<#Jt*EJU>X-8~uR7ZJaQ;LO2207{Yg?P9RBl+UA8OAwDsz&7`X}|K0Ng~}I ztV!~@>8(Fx^Jf&(mPfQ!xK(?d9L2|F+?OObD> zt~$D1tsx2wId=Kd-AYd9+Dlm9t^1uMR;OZc}kywQupYf3$2R z@jJc1x$=lqU4)R>G+IFEnS8-SIhGubN zvWR5fOm4FOkzV{FzQHr~b3&!`tIUUwyo(AbY(KuLe-?9H!F(g+wtNPvx-B&Mj^f&* z@hH*U_Wn`dWl6$;OrZZ0Nf!OUYev$e=_qW!!0iZX@v8pt0xJsTc5wV z6{5)uIe%pLNQ+yh6e^E7)fGl7WyyT#7ixTRAMtnSdO)pSQxTeR*cBETYmQv+Z0XHp z?KrO&G3c5ceQ~M3O#3;-KkP&C=jzZVRJ?okYoM=~?lPE*(gm zRL^>&i00lfk9DKWa0K3d+#1+9lmrIEef|X||BF2q*xAkEK;vVylkl#2|0}9UEeR>w z4-4ty{o3FIlx>))l_X-rtOL#$a)hszGN{z?{?elB7Z!qDUbmbcd*B@amYM|KGr6P7 zyN+yB=g>hWar;n?t{r6MvOWeIHN@t7>g$TT5Ij083~@6mZ)#(C#tbai&p~8l^;B7+ zh@q0sE}K{zl0oc@VF*sNCJ32#lG38iv5)=H_Ac^LN*QtSGDZVlZEbRITH=YmGAUCu zCycRP)MFeoO4%`f!6z_;BO#QBijgD9F;tHNNStC`=K!cFt*Av25doaR;h0HrTRiy2 z(b7TOQ9|U#eB;*9Kp8-$MFxZ}6;}mn6^^t(xrp9PyTEu!8E^J>J4=*PUa&hsm8^P^ zCH@9aG*)AlaN`p*AvJ^kgJ;2Ka%eok*q#C61XbV&HQ-+TNJ8N4RDD&{J>X}Qtf3y= zT$ODSSW~Brjf!@@YHtKa7(I!WU6dc1QjFA>7ENTv9Unm(N=IZI7F*=1@cju^Nhb!`&GvjJ<`L0}sz_Yx82%RQ? zRW1I}N7H*GUGzQIh6V{Mb1p}nDMP7>%wb7+G4Jr$5Pq;39UG&emmZ;vd2WRmSY1z_ zHhqL2^L-whiuB7_1zKaIj{O+~9f|cF;@@rbcgzOV{{mZ{C3t8|cVWrA#5)Bz~rrbj%1|M~!$*UV3bK5h4LQ?Td4mQ*O-murxUrKrwY4`L+%?Ga;$h3)F{DWj5z(EPTu9M@u`l`oAZfC& zmG9V9^5FR`^C+eLgT{5~($h~z@|RbQP=%XYr)ycz$pfA!ViZkG7y$mF@9__w3upnu zAXjOE>My6U!QAA65_wQWjPYk)UheCXdeY^FI zECLjOJly8grx5t8qS|g5grpM28;qR2BG(7kc{2mpExMVVua*SGbz&h`VO1F*Wv~@E zOZ&Th{7n0rq}b>^<&v3ByRsSk27}xE!`Nhg$`;ksjQ{(+3}16w1?d?tw=KvGFp;g zJ7Cvg;P*B?JTk68Im4eV6iwRyivumjOZBAsHTEt zwgg`8UT@Y>(Ltz-KLq0^ybP%sG!~3?Dh0#dQd3g@DnR2>E%*>EyQiTTlW>k$7?>j? z2#JGvO3_-%EzFrl$|Ze`PGpxu8cY(zPg}>R$WJRyA#n^x1Q-%y9fYAI5Cx{g^K|!9 z#j6zQLhSKF%;=o)`-?(#TGB1ky)_mrKe$jES*8Y{X8^PEigbqx!bFjR3WH$BnFc9%$sOs&yQzJ#Aeq|@Vyl`m-CBq~a7RE*AbrIWcCdX7}3adrugt(|&7vhw1 z-S~P$6i*9Jp5rYPR`3x6?*K36yTmrDvPht~GBXQCj*JWd0YAex!Zv+$wk{jT<28lhTprtZHHEYF&#%0i8CErr8ugdr75l5t*0&D z$wa<%n2I+a5PbT3dls=g({|ZbOa62?7^>Rv13T58XI*P-x@@h*ghF=N^VN5+o7y+8 zgs(oKJpWqhxA|aQyU~cjeoHi1Uw@s*!}0OrSi1McW=!P!*Ej;9r$2d)2ag+oVR?~F zHV)V6L^5#VVc(Oaa>P8ezJ?4jiSaGUmDppcaGweF+;~w zR3IScPD)Xsr64#S)!bA|a`}=^+bPJ*DlQpmxo3iAfHcM}#hu!?PDiI+F0XBpkeu<} z^oOvn7-PV7ayh9vrp(Parm#ksp)}m5!n*I{FRn}}=Mp|Fc%RIZ!YhG=V(jiVMWLxO zu2n%0pYphZp%;!pQ#{R_S>X(CgJ!zl9ERU@dNxFH+s}!XAp$W1o^Vu}{-_EsrMlYly zWt#ztJxow1N1r`bZo^{gm6o(1S>gWeD25z41<`5-s_K;8BTrdodb7Vbi$ zaipM5)I*Sey`I-OdD&^nPe*gD)#T#ofq2MS3S*ZvoV_OwN`I?Yiatts3A0dM*m7Pb zoo1}USdZkmtoX`(%X9kqGC=p<1l|Mg3D!Yl&48ecbfJzMnUQrNA<7FP#1uOQb42Mt zKDJ?g-oHY1e%MyWlpE@va|mC=G{Id1^staatPGySEEQ-+40NRIte+b3?(Rk<(63|l z9X}ZUn@Dd6cng348~#1wO0$)HCS5JH_BHs zG?|<~Hp>YJR#HKL7R*@#AmBwMgm2qKSxS{FJ8cM?^1#ERZymA`m(e!gZ;mF;M(zUk zF;SK{^=hD&Y&=kpeT|BU z_poUBCU2<OOLo88_Q5 z*H#XtL{kFHF(Pz#XT;0}E+Yw|ev+$-MqIDq->BonX@Asj%uW+%{n7R2U7lp+N35KS2{{EtRCxy z9Sn|vGXJRb^_4}0mOp$GG1d1v>!BGEZy_uSzgh~&)PI$kIjh)E)A}L_hGoU*8jc&J zrF$Uth07-}9iU1C=n_a5X|*4u$?53ISxE;43?*q*2$hEU32W?Oq*BgDWPNTRvZ4um zP&<0D`O7$pO@K9+6Cx23TNWpp=rS;+VrMWFW%{i$<(1eVC6-v1c-cf{tzuOa77}BX zSJrAooYFK>UzJrC^Cy2qu!FTTmscZ;oWX`o7EYgQW!Edt8i;r&PwV^Wm4mWB>z$4@ zHp`KmwR|}duCDhBQVwd`ONsPvEjD7QX-R8;w6Ai7PgZ0eu8IJ=0*)eCd(R(~fqf|x zofmDl#6FxoE{Iud{b(YrzyY{|D97-7Js+;2PgY%=-DKWT^;O6i{r1E7xmgYqQdRGr zCn*c58YWO@&*~pSt9uC0^htA&-u3V+_QL||VoHfk2nvs=B;1tZc&>IR+z}<&=@a67x%Y}NnZU9d zbMb5WW~i*zGAjJ?iJV)sIAV&VYCRH38nov2D&K%w_zCgtCUgkzi4=8ulu}6Y=pwc5 ziQiMh5;~L23VhOm1`Ea!`_%NXC?Nzh4drwKBYNVjacRRD?6lFQ5{o<{GFyJl%$RKp zXptw(hF>GCq|@~LI!yxT7WbK=i&mIQVD_?{$HPl&i{vqFP_}?8eT&s%{SH?}AI6TC&D&eetqoEM+t~vF+#p;xvWQ{J9@{+a8sfJK0l3FFmZ)X(}2YHJi{zo!~8S~p1<&yk|Xw(mM5;U7l za{)PMU_IN2jL8AUM!$SC*cp}{amQR^X7vjxv{7@uj+Vw`I?`G?NY7#&|83Wgvfiv9 z;_Zr(hM}^Q$!NP;~=lqiwYB+e&I-Cb&g$DO~8u zRj=oilIU$^0oV5+HJI8wqirEl4iYjBvB+|f?NAM=5z`-1dZWLt67)RAnDPfo*<@X< zjK=d*wvnq$2gs7`N{@shZu-Q*wD~u7*;^UyX6t!klo1^=PXE2XU@WF^;?| z?DqIOIcNHU_SJE-7?~jJW7Qa(S*A#~t<9eOPVw*7^l5Pd2ir4h5@~QY=;VKPXvWAU zSNi~oEOlSDS=W5MS*e_nLVacyu=rUY|HG1YRx|UTD7XRp0-eU(&NcqTC$^Sq5}xBa zj>@_BlrZi+Ph{fbF??d!M(`ivhdB#?4GR71Vj=eBwUX1Ewb+_fK^=fs{jVOa&2Htf#Oq44P zM@?R@gZUMJ1=W03ivPS$e*y zdHF`^*~KN;Nd*;^Dn+HWap0;Kdskp=UAsG^xw{z@)G?p~b?6x_fDKN*YZ#j?Xq#FT zhJFCO%)|MZxoUkI`+75PzzZ*DfP4%Q&aUx?-?;sZzZg*l-Tf_pJ$9ccW0afV z3N8h5h7G9?yuQsq_0XBoOVq~|Aalf~)RAMOcoui;473j~iA@+{lMK@c=yarwN$aCG zg-?S8k&f0|*!Gez2muK{Ry1N|>2dgiZpItosvtp(l_tec5M&^@sh$ZFeQv5k2aRxy zI5|JwLzW7tmTnd@QwAQI0DR;t$pU-}djRy~uVRH-Q`y~g4gr+O0H|qn@8un~45CsY zf?I8aTVrPAmBUk)S0M>mv5bqhh!R%ZRt~h{)wE2k%Fckir_?nc4#U|pTOez# z;d@KIp}&v65V9k@;?BAw-YpfAe?PN+Z-0VzTQeL})b7eV_a?Rm@U#yw{@kEXG4#9+!-AK*;`yRDo@M+_@5@=uvt&}h?b`6 z_A;IZKztbzz%SX16QZmOl%OWfPU>?D@JK=6AazTFIRIU_4Wf|x?u>)uwi$Q5s*?sx zSS*t)hbW7WR#s!Tpt?#xUn(bTd3O8)Gwf%sad31gp>7bjJR4Ug(>u3Py10aHlXXgS zYW3n|>}*eHYAIvt5S!uB52Z{wGbRRfmkehbY_k1ucy7p5_*$+ugxM@f&hab6Ih&E0 zv`|ZMbvzD%NQsFd1>K*qgxG2|Tuo77Vkpz`L7@V@#2I9bRguwTnN@3lyvJ15VOT9XlV~`$nlX3P zLD2}V9dQulL03cPQr}}*aWBFxq!d-$&J_vgUh}0HY1v6b+00t>s#c5uK=+pOA8Z7lw=R);oDT{f{>?!%V?(*G2-w%3F`$+nD z0%=usIhS)#?WphIi55PK*}ZVQ()?+7d)_M_`Ls0QKK%r*n-lLk9~OB2QSp%{(`$c3 z|LJLEKJ{GWRw9k+p*@S)Ytu2m2^B?W4%kIDOyWeSdO55(kRpGC$ zayxoPxgZY`{?7&P!Go#XASHB+=rszcxrHRSBUbHdcXMmvUE6UthcERLDH5Nh6lQ@V z-G)9TAh$&_+to2R|1nQR3ULt2u-2VzeH%q&fAGopP2eidD%$6^uCx4F7bekcEdQe+ z9I5(HX0w8uilYIRXKb!WOH-QIueYgFbQzPUFb;Iy9bF3ek#j@y=7kWZxBrMclYz z?L(6QoW_lgL2??(He8XkqTMGR<2N?HNx$!=zJMA^S5_Rtc7i&>?jRgWvR zuIm#!hG;l$8I|5AIH#0|nsGUJPH8_lrLLKlP?{pCSRp4yx2zXZTOPHjgxDp1o!aM1 zPM=n@UrcXMIbcXVR@E73%)Bn56C39lryoSXh>03Ghl8yx`53M}PVtUPI z&o7~VE_zhiRw~)Tnq^Cx6~Bur1ay(r>uj{EUeO(E274_9t7;d2Y_?HuR8mux(=a*+ zA_2Z?*3L@MF3sH1dcCXEpsd7QXB9SEarOlh!&$4gH115P=WBe@0>}HrFF;GlEy%#b z*SxL9GAaw%AW17XM&dtb%~Fy7kE*u{iYrjtbh{fGcXxLP?hxGF2@-+?4;tLkxH|-Q zm*DR1?(PACyUVcWpEI-1?Yir#Rb9{eUh}uBpHzVpQPaIdP^okjt8T6R1X7T1>|8*t zsofpIH)w?(!P5NG{%&e*?2x91pmMKLzA_rFx;g5FyqY0i9wifi|>oFDKh&qRkP;@7QJ ze{%rw;;}(YVU<()b!OIVK4m?mm=FpUOZzb69z!!U$$t8sQ+O4*9|7cPOzl#u*DmM& zq;GV*f^Mp?Q_(&b$R#pOo&1k1*!Hc)E+x$nohnr1+}!Ng!+{38=H;aK8jG^!ywM1T z5KNyRl{C+fx}`3l(rBFH@UbUpx|Wbb{;BV(>nr?cO`PZq?Z?o77HpG$!zmrrIq-=q zcI_Rk=FEqUB=XPPn#?XRQr=jm?wDX2xY{ebZ*HDJ8GA zNqf2*gK*C6?kd(^ixjKR3*GInpTd}6y;v}59@75(v}b}A-42Tp>sex&U4x839nqIk|#h-^`-o?@%6je=2YaN@{8iVJaId0flvK?a~cR-ASn( z{R0x&JtICagA*Mgqcc{}lM8jg>Dg7SzQxVr;kDh*QAR)*XfU9B&+7yl3Z_+gwst3pldcxM1Fr1D5fk+8*IQ*U{p$Y&A;k#WLaM9ts3j{HU#L7Zk zCL;3){O%hh! zgaF-or67fWY5R)9Iu28y{&3l>csv-AN!|2$L|$4B`fn{yeDDXPZ1OC=bWdtu=jCQ@ z4~=nL&=>yTuW-9>*#V(2=GyRlsH($%}MQU@`B#mJP-Xv>Ixpck1YE3PWrM=3z0toyRAaJ zu-r(!vGN;ck(6xuvDIus?Y{s_3%F!_kV?0=hzLsqQ;-ZDG>z0R=NeMM+n0rCC`!PA z9c`$+B`q^5K`diJN|NdYxPW0+C^*>SS_+eVI3P@b2pOk|66RWdN{ny~dOmvDnv<-! zS=E&;=24(y0XmskO8@Wc<{Bakj5d0(vrl?+c538jU;!Nld#pm19F!1A zMMUvX)BI`i0Oyv%T+=yDpGp={G#`Z#lvgG{$yX`V-B`XG59oFum*UNbiO4H^@zB*x zM;$@e=Kz|Z8?fQke>4gxFh=@fMJZ9G0wG4G! zvB(2WxGvhjt&UZ#@SRPpk;si#_O<9HJZ$}&6{9ol)uwA}13WjLqx}y;jI6`N$v-Xz z0cGW^qqZ7?2qWa9Ol;!>O((2laL46rlb=_a5GFQ4Pe`WmAAYb+p&@=|pT*<#=9t5i zZ|9t^!XrkQk!fQr>Cl%x~X{iP^EzRjld)p?C?Qqg4_DF*m~Ta_vTq#j+!-eT#_d1zB}^V{c_oj z*xB0I-^<)`642P;bvM5I@g zuJ6QQV9#gzBf0rf^HkA*jVB1sG6P zHprgF#`%2Z?7>}J9KHBz?EGtudMzweNLd#>!3dL@>Q}Rvu2LLwVqXC!TZ**enQG$i zwL)eNOCd8C_GB9mQ%)1UX3419w7)NA(Au(6wgfY2A<#wKB}*gbr9X8}G}f6ywd8+n zsQo^pBIQG;n?#zaO}G=J7Ef1jydUoO@jy=n{IwAH zoH`bmS)D^(XCcdWq#RkHUI0?GkQaSYi{;lSw9fx0`<}vU=@^&l*tSnlv#jdibCY>_ zW2qoZFy|`9m5=pGuX#?V@lljh40O&^`ctCt(wz`0^0!oznqa%XDmy zbD`rO`mc6Yi;4WsMcSt&debeMS}t4}+=`apevYWsw9Lht&l~F^r!D5t;FR-XTbsa_ zYH+d6S2}nz=vC`#|JkT7&COu6e6-S?+Tp7A`1;3KZ*-}X|94SLB7>1~nbwl7OJ%Kh znYAk7(lkOtUC$pIi}13Q-5M8oqIdcqpBaxe^+T+yy7-G^%RIx6DR@+R<)GQ^2$xjp zj$KgU?J{6SYW>tG^&Hj2^79c@k0|c2886j8#Fz15rNzcIXZ6zJt1_y!5sclxKXg8+ z8dA-532}MRu{L^cs^U2dYKBxga9Qhtgj}5Q*Jb%GcZ_Mb_69O37R* z6rQz|7bf67`npuyNnV^v^h7AQO%zbDTTV<>EKsmd@bQ*HHnR8UC-L^XWRRkOL=P}u z0S#;fik#;w1ArdeWkERKWb#NdaYK4QHm$=+cv zaKj9x(<$NHDGjl_v%1wP+I?U1E$xOrB|Z#(gAqz97vx`P3G!oe@51x*ED`MTWjR(F z-#t<_T-2AVFIy3WkNi2lELVKlg&^_+nss#tbBWtc2c|GXgXpg&KWxiAb^vQS(LRRC zqgD1RmTI>+NfEbLqpF83u~_55KCf%S^mP1jzMjakJkP*rh7vGJx_wEbvD>}U7CGPC z8&4|HM5?bCpVr;MNXVkdY zdzp063mr?@9l~$d&={_Z6%TbNdOOU?!R$N01S5ce>lb< ziUs*UI3^GACl`_USV8@to6|>cxGWYPT<3?a|p z^}UfV+lM;fzb8GQ>VKDffS~VMuwd&eKQan&Q>Z)mo0uO+9ln_&WB9vBIlZX2h5DXu zRx`;EEP4zw7cvtDJ&$(<_cb17IY<PMd=dx0QeHaGoeXekvIkiybzm98H$p#i24 zvV5o&@5qxD1`IWuLa=fr`LF}nugBF2Gen5Kz?nt^7-5i*@C3FX5%}ho`uzwJ#h4MQ z%FQ;Qq}~-TcCqwze(oPjmETM#mN^VzRzHDZ;LsvM;D|dR-9g0iehwUN4g!kKJP4DEXb`6vM&HZ~<8eFj@2REF-`4OhzeGoh_<2 z_lmYVT3GHa{cIcQrc^wsLZ>xeZCuAw*fFCuZG1O&?yl<7=lHAr>wo3At#SZ4 zB+M%M-csVF_TUI{lY^$x!*U)sJ}P-FI10~{PY?r?`N!&7<<&V(TeA4Q}5WLhN}X)F<>n|7{5D$3QeR})+8 zs#Ysd&PQsZ6jn=JBiiqGV$P*6Jz6CI?+k>j9Su)@#R@QsN%mMb8v<2w;51G)EbK;4 zhadRL2o*huh->yNsOs3&c7(#y)lH~rBAZXuv7QFZ3W}fB%+WBOUQCVOypSyVseKNgS2R?tTY8GM5uZrU z9uHVCvbL#RCFvp#T|1}{#9NhHYb)P~xfuVmIR(lL*y_f}q*;PxjDp^+<39`8?kBgE zc%SY7L^OhbUqdzbxjer-!sNjE@nJYg8$2x)S;z2`m61;K|I3Ic@&wnutG1#y*1mYG zwwg={5Oq?by=?Zv8nj)SjmEuPh4OShT;mei%^&t0_;B8}Nh`DV5$Fl?J#2eMvfqz+ zl5#y^TAUBuq*8YARkxV1{35(bI)7WZi0^t^ni7tEJ+}oi#Xqo02|?|gdjg5FaS|-t&~?m%4`mxMB7-`=e+t zR7-(aJ1RjF@?@yZTfHs7OAoQJ>@i!5K5UAZAjPVjk(Yx$#50vpev{neD7Ox(cfTqt z*0uCKr;rYE+nf-+a%1?)hyL2YX&)0#&|f7}sZZJHu2$*fgvw2IJR2-JXlr?h&&860 zpc#L^a&q#b!!Gd})>u{j@3TkugI0gf-JOX7NOvEKpc$$nXI8(X{5>32c-x9vA2mVC z8G@!)iVKVKqM*{FA1+gki~qTnK<^D1xhug4E!X#Bw1JnGhpCD95|KvNEF*PsS_9i2 zvCYzor$CLwVbe%tO4~j(Sc%P^SY1cKF3Kk)<;a?DO=Qlqc(3>^S3UZOD4%D%q{p?w z@pn%-HFr3Cr3pVril^Q_XIhCc1V<_R4w^>jPswDnX?#llUZLQ!>?A1)=X>tFLJt@5 zh_a4bh1=wwC})51xIRBaz5pIQk-V;)zfeWSi~=1OZs~N;-JiUYhr=_KQm90&nyiqB zB8r2@5h((W;&&=qD8?0u6b!6*=5`{n=qH&Rskq`kP6m~-)H&y%m=a4T1}V$1fXEGv zGLm*GnLGymboNp#6Gkl6 zK=zxD(YUqNrhS^v&E%-rNk37cw_5fv=FUiMXE3kzSne?UU2Oo))6+)Kj)#$}l$2vK z!bO}PV7{#0dSMb2{~rbmlVq@>FVkIXQE$9|u@-_Fo$lVKuX2C?%yjzwS%0NszCnl6 zRw1@b-sP@y2G4c6(fgo!#-O{-st@ z+ai}8-E{cqZ)5EgXtNTDRlT(dU5#=F>SOdVUG0Onk(Qv(_9B>Tx=@Hs=_s}guI5MU zseX+;Z|$rQj+gC%pa;W>Kj==%u&ab8@~vs%)vabP%>TTCO{e$dzdpk0 zlU%Ap>3`QqNP)+*WCvk^jfiK528pIPp^x_EjOIyN{mE*E{oBnc4^uB6nc$t!zZG8LpF!EoM6XC!F= zZ2e19WKNG6N$tW97bjK{F5i8I`bCgJI41`oZhAWX3d7GRScJ{gaH4ETBv?DCkYH>f zrdD#B$}Ww30?Y8`R}XQHgY}^HYc6Ul>fYIbM9N(I!bIDny4?;y7UR)pqGNZ~Zf)rR zbfh%dHLiZKjQ0fU>YD0lp0#&LhlbUMkEO*l$O!MH-$J>ks#-;d1iOmJ+^{{KNg1Gg zFPNLTX?DF-5z5>oquJdc$GmGe&Dd07W+M~sOO$%Q-XAY{`AM{yZUNZErd`in5PbvU z*&D#pJQgtN8O0hnwkN2Gi|$u5K4l7LdOejnL%vF3*6qLTYzCk${?36vZ^XFWo0)xjr z*}au7y@p{VkVeHx_L!wp7d@}s{Svmx@@Tt+L(p#*Sq(^6hpD5jj+v%__g`W7niPk!K}JpdNu`GJ$3FwpR9~{)yKVY8LJ<zlLlZyM;ce`W~IJ-Tk|IKTf2d-FU{{P50)kY6GOfDw@)hl7sAl>`*|qkYzAq|8?A z(?q}*+IFeV3v@Gkk8{_j9*F3TrNi9Y*<~qUa8lE430P8)1Eg>WWADUYQvlO=Jw5#3 z|K?12GG?s_S|RFVMJbr~C0l94NKxPAmX^XxLbOo85F}QShH{-6<4UwI0=Wz*zA8)J z{dm+6J$}lC3Ty$x6CEh1inT;_L-JHWNC_NT9IuED5SF6MR6em(hz@4IV&_PrB49-0 z_ATZl>4!;w1m<9YWA=J>#vY)Fro zP@|zxJ11W7d?bK$ExR~PkD~n5q!6!TrZ%_ptgbX=zcHiN@E^&yfj_96i$#(B%N5BtuSwV-NyxA_$_( z4JP$7+6mm%QOORG&Q8w7Wt2MHlK$KMB_M*sQPm`%S2KH^Kr>x4)i#_<3n}`u)#WaA z(ZBsKIt7XS4oO(z96;72nunDDpJ^rtu+t3zaeGZ%U9p3hD? zSf3W+{uN>yLQ2_t89;X$E1FpuL;Pi7_3R%`0R!snEH#~#o#RSQ z7{synV&(5Sw3zF_TBced{^#%tG+Nkn;93bn}yOS0($VBfQARGEJggw~`g2LXQk@Usab9ClVVN7FPVy z8-N?=fJtD-Bsw_hg6-Hyd2N1`it!%DT&^0xc-F;o45=AoSX{fppiXPM{=~t!oj5ty zmUfLKzN*HV#3*1?TZ77CBR*R%_|;)fQNhM)UTYR|%b@EYal!*duLU&fU8&aw<~FI!5dYOHDug{93OVnf z^Ir~Yu;bG9oySr;DMFPy6O$hzC9tOl$c7^JofLf?x0|+yJnXeL2er(t@8+F47EV4u z0`u9dpT}_8mu4>wU9%~IV}>O%LeHeV;$9Lu;1b;=T@Sx|YXBsK25e$nBI%qOM0sP2 zc_PTiMOf|;&%N;anvnG%$J>uNQVpMJWkP&@7$R7z82h-CPsuVIpupfCD@R0)yX+>X z+7s&-4NZ-!0xzYx!y1R^WJ*2XG{RS5AIH^3hEzg3`e|w=s-f*0TfM!468}liNFO!W zxul=s4kO+Png+E@wqLJ?9dBG=|M~Z@zkNrIQ@*|*eYdQlk=W1lnYC>0;2}kMgW81U zwQo?HO{2UU>KTt%6GE?U6RZ8~nUp_@>VxP79nZSbUjt0}6RRc?#?{}$Zubg!yi10| z&89Q-*66r@l_(=J-(>9nEJh(qRs9u)l|_YJEc9ul~xk!X*TbuE=~Ne1>@(ifskDFk`p6_@pKQhoSyh%!8``xSP#ui=J_H$ zWHW77g85jNxnipVdhw*-DSQTv3c5(6ug-3Z*)_LiYNkbB;H@1vbyS{- zap19$8TA_wOtC#;(zQ*JM(WT-9m!!?qu_ z`EEk~utX_=(;8o3ZpyWym2B2f;&98T0X$wP3Bt|Wb+&Z(^w_9VbNO?8d*Y0qw60-` z8w0z}viGDn`c8piz|$|PbZNc(ar5t(Sugh>95c9X(XRbhaQ5w%a4FaLp(B00%2|ME z88tkqd+!gcH%o*8nlf)ck!_{n=Cdl+sCGZ9S+%z^(auZMmjM!6w&-tOyLftT12jRE zk?|fnhcq}=vywK>vW#0(=y)kGD6FB~X?q0s$vsjAY;l3*dn~;VgVHEhQKJgqX$0_U z`J?QE3Yd%;>{2>8D;RW;pY_kBa7PABjkASQ^qIYo?83Rk-fLF$7kC8R@q^F4Vs(@m zk*?woWfA)Nh3CNehSPdnx)LqL?B%1qdSoKWL`T}^nSwr0yD3_T?3Yr|V9jtrzM36+ z-#^$eh8esGjUcF`V=ZL4h#nvmEnl^%(#strBloLG2yQo9JbGmA8#@dY+Y1KD;P1gn zGKV>ZHm2Br@$~X!gXwhgsl=3QS0DUQr&y(Mwb8cDc{35Uj;N{ENlFwhsELS$_#mIuGXw8yocT zojEZK5Bn*l&u*3GB7As_z7NcToxuk*Zi6C>H$tdQo64t`4hlOw_JBr{US@PGFR${h zFoFKyQ^gss&q{3W1P_KtH5LkSg%G@28L3Ze%nQ$C=O=z4L7dUDkw288VEd4~P>Q}a zVQ5qm#xYu{;_?jnA5qwOYi7VF7l|f=sDE~9z{{3Lt6}44K7H!j+WH~ulgEA*=n~vw zR~MX0R4C@>?@2GIIEZ#gui?}ptaf8;r=Ooc<-L8rO!#ztK&)S+9Nh;Da)o{@;)dci z1Aq&gA~3RUX=HtrQdwpHl$UC8x^y z(6j~PFf+x+iB=Qs)*o#$Z-=!ZJ4ZyAyVgJR%Ry8vBp0^Z}sr`|^tGXKlb=MV{ir ztt9w9bY5jRH2tPxT_j*4-UvS&T54Z7?%QZ9<@b>q36GeSPHww^y_7J75GdY!01&FDbiU`GeDSQk;U;TD-UZfV=4;`D z?6QVFKBylL5#aJopgYhhhNE{YqhuLs4{$ip%eE6<_rOp8qG#a^MCWQs2saqtBX zp6i@q)$NP)a%Xk`wv5vws&?lACTVB5m_*w)={wTdskGcLs2Z|mioeuLATt=p+I7g! z+pZ9QXeo=4fHyEJ#0OI(&bh*^5i!9Nq;-e>U=W(YGzhV3kvI4@q=(vfNKn z3NR6smtV_Hm38x#)HkXkr(LzQh(j+-_KaBuCDklj9+)@z2I6uuMeYYEy|He8m}D%t zwT%0)dBie~+pB1^-0ktcIM!oJrRM~5yMSdBiupu=3i)+OUvWW$|B_X^5k8`+^ypo5 zDFYYZnV`q2{*_zX!_o6dH%N*`kP={)znAwN8I`kDBZLpsCasskHQ-CF{zDp6nk_@z zp^jl<+m7q`Q@G*7DBePv!;2f%c~w&pepy`^+9mNA@2?tqX;WNP*0rCxXQz|bK`SG2*S85SnA;6Z9tT7`pr5^0 z_wYur6TMs2SZ_C`R_dp`XfeGM&F=_atuamX;b~J3e~G@^j_lJry&3*RjrFuK&pg4Yaz4~J5l+ESQjT9k07=cHgH2{A#*OwzqqG93ssV`s;)H{&sUo$kB;(g8JkAb##PuVN0sh zq6rn!hH1DAHza&jjpz#>@O1;vqV7ot#SdGAl;%!b6zUDtkDv`2cGj$W!RP`+uF(hg zyx)zOsRE)`=tKB?Ama6LlfqCS0n09lVQ$!i*d+Rpw6%M#URi;nf_-S#+P!|n=%EN+ zX-Iv8^)!wrp(=e$CYfFep^H$XwO+h5?SXtF zwkVHele;6h296yzR1cyoLL0X};Rf;;O`?2EM10Af>e!IaoI9wGVc%-s_j z`Ol%#>K$qY$4+Lfq9e+&>KMD=w9%Mws<;WG^nSE9F#AolnQGDYBBJ)#5>z`;*F1L7q{jdi(@43tfiOx1!l)tWu>zcJeK8SgXaVzS5Q0T8glBanNeK@-qh$oXL?&-4RCR=XplN zD2ASVvHC3D*P^ehI$s8UC+6neoN!TF&*nz`u1t#jVZ8}2HQ}Psu$li!mEKctG!wa^ zr@hohTSON-6{k-1or~1CI(uoXrJ>PGliHp`LqAyTdFG<=)sr)-fl2Ow zYN-76Ro@8X+ebf2p{2k0vmutmmr%^N%19$7!?&ZRF0RZU!Hmz_yT%Q;L><*($D=#M zCd*|CpQ?W^Q7TO06N{zIfvck0hT?VoRgRucC;mg#y~T`xrkl~%2&hf3?) zZrnc{cUxu|L+?*ew8=CWlP2JQ4=Co&WIqzQqv}L))mD#@gF-?qOmR-@qE+o3Lj%Q2 zuNqwoi0!{4DXQ~N-JiTMT}G*|(F#!-fGk zWH52Ec1@0a_g2Fykl3SRU2gL9vQtaSHO22IMxf{kPw6E%KxFCfEjpykKZiNg;~h2I z3m~j~*7d-v)G(GSz~%Nbr@>irpFsw=3`T&Vzoo=y|E5e6thZd=o<`X`cOp>r4$?5W z^o4871Yye>ZjIA>6~Nfja>NGlXYsaPzU&2XI1DQVrwEFrn#BH*|JMbeo$;&6cZ9X{ zaZTqzZ6_u5^lIC1uI~(3TF-Q9{uR8-M&|nd^5)nrEIm-)}ZGs36y;)U2s3sU$Vb&`elcBRvf z{nG98u7CI*)P6wqSDJEWo2)ljbk`h(+uoj_3;u=&Hp`LL+vt-pw0kT%LxQwhUJ*jE zs;dqFBm?j*AjbQJhCOooEEM4a=lUF5s`9G3!ZlKp)t zLGZ}}W^kg|vqb7$c*MQfuv7lO=z>@7A)BSMkY=fa{JLI8m;xY0IA>oT6;jM?j@|}+-KHY~<_A(Kh zB4L9v&_2Zxi(TmB7GMjw$WaK%tQ**_D{P^d5fB%tw*_8XioA{`sDz7BVfWqpD5w<) zIh4UA&yG6AgW;YEIT%9wZysm-7@M^M-u*X^w>ARU@WlSpmGM73-s#JV)>ZTor1>Z& zM8ji;M*F{}hL6mxZj!GkInT*|f;3H-1aK7}L7H(}p4!#w50B}rxL@9f$Mks~1jFm{ zv56Us3oZ34A~Gu4J|r$aK^y?(5uKWrZuzla_3_u4j|EQ2DESD|fWQS+)xogEA3UB0 z^#9;-gQO20kAeN*aX|n~@7TCk*3k3}?#RT#VrKvB>JR{SX=__;YVB`L*UrBqxt9I2 zeCYb)>m^|2`9lc6{N{BVCg%!1pQ9^F)P4nq0SogyTihJx>{Gf$XjUo!h(tu!6-z-M z1%4kJYGv=r8z!w|MgTa^X!}CBGhAI+bu8FnIGv7FDgCI|0YlbXzae)! zi`iCG7HUF2+^UE`!(%WY(Q&hGL3RnFc>E*?^SctW{5?;PQ?=nB!_X9@7AJ1i|N0|$ z6`mq2&#@z_Ow2U|A$2C8_)E2m1ui2q14zkOLN+Fg#dJOH==})X-`loF}Nxy319C1NMi^7+YLR$8ZD$u^F`vjdB_qUN0zu$lD zVsQmfKr0z3L)yOl-s0_jwU_;cN>N4TU(Nf)2#e_!G7+Q#4cX=+le^SlzfT+r2%#Lv zHO5MIzt|49t2?BKR8Bt>mE&EoFroi^HNOob4i4>)79m)c2*9^5q7smayV?s|rmk8@ zz>(rZ_$}W@hn1var30TVd!yNH_T7x0hT4+CcO6XM;Uex3ABmGKS>7a9sXrK5UH%~_D#2up_zRNc~*p|D}=RQUlZHH18ct%0k-dQX@Nw!n&OIuECJwcd(RhKb| z+64;x4NmfKBADSB$ZCM$;w55DCv!BBJs*@ynus>0dc@BOmh-X5j$Httj_(uZI(TfF z?)2PwXJn>sR!n3)^3P)PPp$F-KrD z6t}YbQWoah-9@gzX3Oa`RaW2C%!Tb|@RU5??M(>O+w1jG^k<*dznH&-o;2q4qV8-* z-ujNt{j=Uyju#c%j~@LuvGy7p-)_f!yx_CX?|68i2vB^5)Uv@njnuG0D1MA_TVOgm zgeP){Cl5y!40TsGn-1E~_q27mTU=pRH?)9PjBPmip+ZbQ=D>SBazxleF~VGwVE8$5 zc>E<^(gBnZ^f_{5+DkDc64?-8%G|#Z$pW-NvLW()i8o8Q&HL}Ntl=RR6c`+ElB^zK zVI#H1DcN}aIH}?hr)4BK1s43Aw#t!1#(DV2z(M8_6@Sn4MVwb$X~6H;sLEQC*MWyV zz7_|cuop6t$^r=qkn+zS#(V_g;a(mojG+0eTo4p|l_*I}takYxC8EU$Y_4Nuus-#+ z5TEQzt_*D%Ie{Ao*IXn+Hrzsa#r>)zHL@)x-%v4gnArH~ z6LKy)i*YIp%%tgFs>hc@AZ>~jg{&7~h7%6e zr@LNqmk->qEtda#h~#h8leuwOG(}_~&rv#2T_n=DSkz{SS%ghzGVfPJlE!Lhoqo_w}TgKv33xvIIxGPIf2pKqqe z*5P=oP5X1@Hm13j;{U#EowwNSD4{amniwP0o8u%Rf?)~Yvc z(|_^$MF-LPI!Z?VhrJJHby8D)-EI9czhp z!T+9(Zj_d~u%+xhDNlCL)E^3{Na%khil`Iz;tjHIumq)zZeaV{>ui&IQDqIpm1RmQPT5N-QQ zxXCqyYsL|)y0%AI={C;EeH}hcWWq)JWm10s`aLa!Xr(5KyGa-8T60)``OV60+9#?u z7*>Cm|NUViDAOSvd}<;F#WyD=RadZ{E()+t?N6tvFH%H4g6;K~$mpodxDG$SfPLyS z=XOlBK|WN4@|@~n=B!42J?3U?nYXufav=3y%jEi2DHvGG)#Nk!URGFu{`bCLy`>82eIPCP%;7YA)9Jx=n#YeV=Z>N9_6jmK1(l9 zer-^uJR(}ravOYA2g0cKXJQ(e*Zp+>BT`eFbcLN~s*n`Xf-v2^k8=DNW-QH?K&7I~ z`^)LK?=L$AB?n|GUZJU*0_@dmAiY71TT9r&?VnpWqANnjO>@7AA*9kfq#1VwA0>%| z!;E499?@-`{%AY`A#Am_DSZ#m#VX_(KVl#8xH z-)Twt$VnVvDPHb{tcxhHEnqLUf8he@3a8yCXFkDMd`9O1^QzFsvVp>5VG{=7@pA}1 zaDf$%!aWX@R)n7GK-hc2bf{) z(5%K#I|zUPh(Q5`K`~tpgMJu_A>wM&T(k=rp5Q*@NckjR^C#QCO3 zsNKk_`><6!Z!(#v#3YvkI_R*NsG}xWF2ktPWS|=$`tlIo4=w5zE`kCQ{a8#!*d6`a z6cGZ70fvH+zQhD?AycwKq2b43@Wo>3#B!sNeERQk9ZCQ*z!L}p{=e$i@zzbS1Cqbd z{{{HTI(Ibi#p(Y!sE=XE`H29!Ka%ht&Eg*b|8Y>iYsSKZ3C#W9uH;S=$N#vJFWk7u zcn_x@J`Uoj1X|1`Ix<XfRc$WuA%A#aW3A(nefpXGQG0LgXb7=6*nc!Y^)^)c<6Oo#ZS)Eh0Ni40wTe z$gVY?gcb{Sk!`6f91wakZjNYP0&*KnBSC4lG#sw-+FNMd9za67wG+w}M05KN2pg@f z4KlY`_ZH$C+jgtGnom~;!;?f}C3sC)sBE*jXFbc9&Yhr(?;XXSArm+n2b@3@~nVGMhnW}DBu-8sa?X&&WB<8vKVy960xM%@Gekog0%gVe~x z(D9>v50!!kc+GRMwb>54Nl7c{B)#d*{IVjn;0(8otF}VGkzD(ZdC?jX*nNx=6*yFE z;xv4c#zJGeRM?cv%?LpC{V%4lYG(BPzqMTa3X&Qi%lZ-DxsA+{Q3@=>!{Lkf_c5(& zmWPsmN?k6($m~BBWR!3HJHWKJyqL;XnS-|=^`jUGF!j>B8iEXHZW0-7Oc4 z8f5~jG@+sW_1y;iU0WX_fge{^@%^GS?$6dOY^vo1|8X$mFPWCWLhR%;aDE!E-ipFX z&LeF@lm%gbc9ALaY+68epAq|9Wx<#-+96LnG|OwP@i zn-%8S(2}Ok>)kGJ`Mi{jstkQ{L1fo|qQg`vcVWfP0&{a9^9_9a<;ywzU4qr5{pH~g z;2ZXitC$d|F>SK_@`!d*;yJyIwDaz|DEbNKVKv}w>|XH3rq@%gmJ}285CX(dfqNA& zd!#3AyvWel@gk8YWPITs3@OFv#7JXQNHFL85b(QuaLmRb z1QABJ49Tp7XGp=+b4CwtAsnPFXd$dGSxBKW)RcEyfs?E`2P(Y1l5+TaV7|ak(l};{<&qL?pnH{6Hbg@!elV=#r;fdozr|^zJuWZA5#PPG&pNs| z0i8aJ`A>g`|I-&`&kps3%K#A1<<_{=MlI%}1`S`z@`OJ>U3Nzr?aR|Y6$25CcXy2T ztqX>ykN~-#IdkQ-(!|@UoM*Mc6tA?5EFPT^Y8nMy5rwj%BNGV*93D(xv*m441BbfR z3*7}R(cMd_e(ZAw3fRyo^t#Xa=H_Gv5Lr^n5on}d#TRQ|(2MvI$mDRNmuXEM$u(Qa zRhFWcYob{zw6ah96iJL$GlkY{wbD#rxGh|_wo)s@*M|BxU;gul*|%rb#hL}@V%O7> zPwyT}l{5{-ywr?Lz*gxxHPJr`iRG;H0z-pl&ef@jwC1Y+maF`J|2g_`q9dQSF#A^g zXWxyH7Oh^aXZQ9)rl+TlEe4!QD!Uu<2Z8ArF2fVI>8wi3(o3ioorj`c(q zsekgy&r-n7-FZ9tM*-E*4%enxe;fDiXT?h)jV^xbDk+Cx1Hod~j&W)mXKZT?I7-bP zmimf!m9j~sM%Uh$@v`6y518wy>K==x3m--OZ&<$?da1Myoy3p6&2K-{_rEebH!>Q- zSA6-9u&N}Zk&K}>al1FwFSzw1B=Nq5w5gj_i6*Y8GLhO0$uc{lq$upZtt{0E)7XZ( z>d%sRB8|W!UHNtYP-2ds8@12la6A>%6wHbkG`F=$#bi2QI_7ILMxl65S@zQ8X+)YJ zO1Me_Dt+u-g;oj4A7_Snv_Z7MmiISa|t z+cl|puwg-2vlsSQQzyFPC_a&3OcNb|V*cq%yk2WK__Ezc;x>TzUUB9{>9u)A)6|J< zdlNYq+^s!9mz3myFmy;tOLs_0H_|ZpBLmD8^Tsbe?|`F9MyNrc$@_le5bDvE@o_cUYtL%h-*ewV zB0bqr8(`ExGN$0`(&#vdS~4!lhwbAZ`S+JNoa(WbXB76Xa`_3;@}_A$mk~Nh)TEHa zN%wHTXiE@NZ}5?J;H$&*!OvV z<4m}E4;P74I2CK?>vc}nS8xQ0umv5L;51yVSa@!Rnp+$(6$_=m!M8WB0Qc z3{ZM%m;$oCVoHb=NZMy`lVvB`XU@odmBq?{Q3k}=XU#|Q7urMj`%p}}u?%HMz6vBg z^F9!^&rsdU`wPsl~NLZK<|XszoL+NTq6U{Qgmm`rp8T~^Ub zJYl~K)J{B~vr3WJBI!syaM`hN{%K+F*QKncN0;_SmVARQ35PB8M2NRWNg8l??WcsV zqqk3S(QBsAr_~lX2JuTu5U~iT2SoSk7F|dx{Zla| z!w9z+GCa+Xq@i38vlXjhDnrbkEo@z&Y9PsIS_46pq-~E<1`x&pOTvH2W_ep=S@LDk z_$8`4pa~)ecC8#VxvU6QhB1mv_-!r}78`+`kfDqqJd4diP$pL)s5Wv6 zu|a{@dDL~;WeE9R`@DY^*;OM7pAd{+Zu6Wo5p~!E4a)g1Qe#`Hh}@9*4z+omZFt?- z1r9ubW|4x1N$AimwhOZ0uRHEU9B~nLVTJp1e?yI8&Ad5790X6{c3S328=eCAy-;QD zmOrhb!~0-O+Lg5T(Ua)rsfD{Elx7Ct8${7v8&1(fRgut0F53TI#-IYQ0uq4)|BpOE zVFO6fVTAwJ-*{TaXkoz)`@hQ=RsbYinh=Zbzu~3-PaZu{_D1=j{te9q$|uS`V1j^* zK(*3Wz2+&j=|ZRG`cxDK52r$d{TJGdPtXViqeY}W`5P~yJQ5L4{)RRX!{$GK!v$US zKYt?@Z2RPI)YAYkb3e7Vwd(^h8@hWMDxc)h5Ee#F@7OpTtz~#>Iv<2SF~8t|`Ez*% z0Zd)o+p1gYer`36mJz#rO)Ekl1hi@XB5C(`O zMCra$s+*~er8r`${+5>Bkw}O7iT+z@nzB2UwQPlB#A9MGlc&oEz`Cv6__U(xD}n#A{Sz67%02h0?AKQGgoJZcT-^`^*O6GVtBTYL;$8${dZf`^-gc!`hDOY zUMnXTZQ(>gXdyBDV@XgvDgj(c+0ENv>D#dLY|@lqh(z95gqI7N}@G-m{=Q1=HFuxkUi=T&9@^?K>;>BB>#!5nFsHC_rk<;}AfR6ycx}sbZB;oD zCK-hnlK0FH*Zy+CZ&x1W+kQ5$VRBulrE1G-V@Vsf@OG{^!kUo+jrj4+&7eOah#@=L zh(anXO5xF(B37ez){^H%Y3p1p4sB{l!rRt*C_iZWn<`B3c{u}_;3|b$vZN7kl<@Gm zp?s>$Kbi9Mx0hG4>6+>rx*0u;`Zk%rVUwHLx+ZZuoJQen=vF)9_PZoj$&{)HCmDLC zm+nI&AM(3r9QF#R_Z{r={n9t>3fOJe%L?@{;vuDP6Xjy_VnHA6nIeYbc8Riv*bd4w ztlMo%NI8e>OAByB9m{@eDQCN$H65<_{yc^)iR5RC##Xj3D=g812Cf~eRiu8&JCes5 zVY;D3T1h)VTPr~*uhX`6G~WhS?ds3)^?)pw3$`itMoz#mCkA5=3`!PunDsWwk!J~l z%_E0f?bR0@_nGyV%vqdQO>&(K_C}i!7ZtP-gItVw8i*4YkxB+?@H7dmd2tK1Fr)k+ z!l^c>jaT7HqZUtcHbA?$Mc@zD(lnqU=H}-cNq-CJ5yK8V!x=Tf`uly1XU(x*OsMnW zEbR7l*|S-)yMMj*wBQIkW{V>D@&(^s!#P9@uM#1pt+ApodxN$TB_J$@`m??5aYd9iu?^3f@LB{Af9miJQ=G9s`J4;8-=b8}1UffP6E z_--kzKYm9|2B^_e^mFki->#&9CxpnfT;8O!9#VpLDRvYCB=g(YyL%d*713 z$FH|n)fYSb{@lxSfKMV$w+T^EXYLF?+RtTqB$F?6#|wf4mvm6@t4)hF)=N|6(2i@l zu%e_J9ec^g?NJ>cmg*g^bSeCpi zH4;~(WKi2a>iHa3sNg^tMox+BbrWHTB3>y*G({rxeA291wUjsttABT-Hc0E!25FAL z;1SA{7fv^@Np?Rocp97*Zi%)Gj2)6waP=uERp{VFni={6>7)VjF}uR{1D zN`Ai};Ks(&i|5IxT_|T08yV3FuTQ>BWr8?}s2ZySvMVN;*tQH*&6xqY<%G7+RNGYF z(eh`ZLw5M$7FFLtJxNC+q1^cnZ|r3>^L}v}(Y5%!(X!6Kk#OD-t~B_rQjqa>3G#uz zC{8t~LkH*JA&P@{L0x5;ALq7UP=b2lhw=jn4lrv_3f(|c8FHyUv;Bdankp^^N{1?` zG^`|M6U9ofA|=C}eW8fHp=CSz6TyHlr_2yA?K*cs!;!T2Y7e0;HSo3|I@077MI%@LAhBP`YdzZMR(nY9j_E6ms0IB z!x{JX#@8Yc4yiGf8UJaL&#opr8lg9{0t;AU6R9WQFR*Jg%NHLDIOD!vCYEl&T|VN_7aN(2_xW7T^o2QTOuLL(50?qm$lxio zq?gAol>O7@@NHqhiiPcbWtEMcZ^o@@6{-Kob$|} zKVWV|ufC)AlbyMz-?j~xNE71G!`>Y7i#kQ_JMa7%T~N>r*PiES87dJLqGPp}bRw-hbcB%>T;)jh9CM>+gJ+H9wv3U?;XTQ=B!zhnuEekta*Pm;Z?Rcdwp1&M$9v zaNW;=C9dJsG~Leg?z5`FSIT4J+fu$?C+`UkyH8AK!|ViRPB^`NBZ3d-y1s^9sC)Ms zuk6Bx+sGd8t{dCO*ueS zYNEO47NXO=HkUJSbDs_PjIVU(bt2K;&7HvFVu`6puYMGYx2nxlSlC7f+nFaA1tZ; zEh1)fNSok*hck{z50Dru50wsqTWYY0RNy9NFu^p32mrzgpy>f|)`e3KtViy*;HtH9 zd;)QtPg8dh@qD)gHIxw8k%XJ~yjaqDiP0O~8AZ6f8Phn0Ls=Z22#sy&=T+%rdG5|y z$>(zNREOjXl%ZgAz0%8w#lzNyXMBr=%*SZ};8dtv5%BKeIetWB2&xdqCHz9mur(sHF57J(HP}u>aEhy`lu)A zxn38Cx%Vfz2n$NB(<&>`eGO03xcaD~J;P9x3;zgf7|;2kD9VB8*ZvwWm}+U<%?*x%(M3d6n*j7T+PHU_=Sk zJpf+W3ma6uwyZ)IGt4qmmYLrdzm26b!B!4Jazn$V#SJm-M6&7H*#973;}WO5=gH~8 zjO^GT@!2Agf@1}WWFPxxmVZl*^jB%2Ko}EeB~wz*+9O!cvJr^b)DZ+vT5^#Cb~sxe zWl3tqZDwU$UgSb+Kcgi6)RED zf>oaXZ!nA)00k5Rss3N#L_tUP|CbNCa}GlRtN+umjFO@WlcS(O14aH%P~-m!CnqT$ z3J6YV@&EWrd-NN0Sl0i=lht$FFe7;ap1?4au&lH9e_&Xwmaj$F6Bw2%0g#V-iYMpl z0WlKO-WL_8WPn`}A1aY?KyYEnmzr8}09d)Ixuw+&geh3p)!jpehS4@SG^~Mv);m5? z+|cxG`e)16&hHD0_6-#?t82N{^S`!tUZW4JA0EYFZ0(+&QK3)${(J2KJ~@9lzq|o} zZDI2@79EBl6821)$zoY&!1T)kCD?3#!nl&wvhWmiD5VC4<+Y{6R~%+Tr=xJEUvJYB z&HnCAdcS^GJcZA*l*plhF%rZ9>*-Mv#mH2-f~~U^yg~nvPA$*c z1N>|uO;{Kq@Tm<%wb%1%OfOfL6L{Vzpjf<`-|Bgx0^BxF_ddh2dMn8a=C+j2>Gn+XU}!e_;yZY=28|5>gLuW07vW`$8ZUf=kSZ z5lOueLfYoBa8dB=lHhTEfwRfKyDND`^=tzJ0y9HV?^HDpkO84P6pUq%G*vhj-Z%L$ zAVG|xPlPq_ZSb$m=s_+f3*Uk$QVdpl_)ekKD*0uF7MefJb9*}3mmU;j!A5wjTZwDS z^f@o&WA`$kGmE)NL9%*v=-h!)8P=`}KHs)7)G~F47+o~|qX4)HBWge$$F>13*$So) z=>h=<@m_W+b;@}!))#h3fjw2bEY9C4(Q_oXt5`_2Ru=KhL)i_>2`tErq5$EdB(^2i z&^y-hBteGq(l>rtvZcA&z4jHoCch5g?cP%RNSz>@L+;Yjc!1M~=EIL4tB0T*A3+Oo z<<**#Mn@birR`)G4QK38HQmv~zma*4?jKQgfy_=EjdSUYdJ@k^$23;N+y3rs#^Tou-WUBzBcZ{aHWR@a zk3xNRu=k(Y`r)qV;u!Lbir} zGe5)Zk#hc`|BmEWDDwW#YN)xw&A-Ms=qglLJ!{G{^$}h`YS)A%!_kytZq-qf|b$$^<*kU z>1`q5&fEah_77A`Zk_a{zC11JwHCFZ^*6G2^YYwOTC|p#>lA_d3N%5y)DCDfR2lO_ zkPaeh*!Y61*8&>h+!V;yOM$kqc;GsTnQdl{No5Oz=`_zzYpg8(Lzp4cktK=S?7W&PdY#izRe0;1LYk`P1=9{~ ziE~^6lVc7xU($LKcj#kAM)cB8vxV?Jpd*x3?dl2hq~9`=S79qT%@O7+XYOLQEsk?Y zZ0D%-SZ`)4t7DUrknPKbiH^Y4m~LR1Cun5C705Sy%^9FuFZtJdRY?H~`$d2&X431b z!H{~Q5^OAFJq5c$%rp_Ilo)+bYOqZl!OX)mztUwJg*sau8IQ&k+DD`+K1iovG`&DfV2M}S;jK?If0ftK0aNH`WS}eY z$3N-p?C(S;5N6T=Urg9J^V{Dc7?DSWYQl#m};3Q?|drIC_78%AQ?E>9`BQujn85YKm0ZG&%LSPGrOZhfcmo4-_pFMW1?UVgG%UC zQx+o^x~Hh>5Epmz1M0y=Ibv)nhn+k+qT+++J>kNRZ4P2-N7lE_$)pcDpE2oz^fFXg zshNA#`P{TdZRu$4dNZqP@a2(Yzf$5-z;<=D*FL z_Xb~>lRu?iS8k5f3y(L-^CCJSmJb0rL+efTQWYke?B=@PNe0i~HZ2lW-j!m zJ{fb(=S*<;@T2?-oy}NduEtWB8WSEN=u+HoCmqH4+%taLx60hr=e_5uwESeG#*qDk z^j}#Nuf5}s(tsAzX4h)f1PK~UiXT)J7iP!5^-V6k=18KiN^Bk-7F7bqGNZ#QWO07$ zQ{VN*3O1DT|A!>y>-5g*TH7(rw%;@V)wnO$rMR@4L6`w+xPMx5@w;pzRgE`h zx_k?0LL6dq3^pD9wbXC-;+ znZ`SF_hDOR@3uYo{gsj%&7!GqU;Tu{m2|i1GAYaTJUZ>)XY(CXLMi8q4qcu-Bs6>8 zKfEU8#V?!4JCBRaUbj$(dN;F}9Hnar?L14q8v81Kak?5bC>9DEFDpEAta;cHe{uU$ zL*lBSCFnr%Bw(UH>D(LxRK6vUn_$N6$a8q*J-Do~0FuY81A5-xBr*-FE*fi#|zJA}OEoX>5{28x= zhn*(YBrhIo_$#IGQ+FY^b#$i&`15aQSyGOid|uN-L|H6+vEXtX`{7!3~ZBZ}WxtMf_ zQ3mqB1N;qpthRJuLHf({oY)!dB#Oysia6g3#h0Z&-@H(U1HW-R9|4jZraxPhBVuEw zo(5jpbG}rT<5p(ModPz+a*SZTWEfFp!cM1R0=RJPirMkH1&$JJ7<AtEY{Rg4On&<#s2 z{4xSxo`k6d()cPYe15wAUfS>WAckT-J7E=EZ1lTY$g&^gH!oz2f``xp3#$)WA_eM} z#^sq7<+DPRRnaKD%R7aE0~Zz3;*_l702=ndxwE|5DjFUg1XDfFa}QF|vIMDq+U_)n z+-c$%JWIGXrYcUUN|t2;8*M|GpS_rF6G0h;L?2mH;HQj{wqYOkSGGr>WX}B2cl?V; zQj6|HRQKH}{jrOwCX0j`i~cqg{2eGhZp<6zE21wi7P@@D%$SoPQv!Nh)E`kyOIPAL zO(|!c-GNm~YmsG9hR27NJ1;E4>d4Oh5&NKouB)F^-4IKXvdonzlXIkmmpw}Y=OyN7 z8T&0l_Ar%#>Md05GfVal z?~FcJ$&}g$fU`?JD0_TxX$KPVR=BI+dx=zjDJk{+NSIbyDZzsmJW9lggFIBmjX10{ zw?Kx*k@@5y6WWl8qNLoQs=N_wRnaPXx}AyZ|P2KuVz_3$8>dW{D_?+#DrqqD$F=p@ono_wq{{F`#y3_ZBJvF8J8THgA z|7W@>dip;sWG77hR!ZG^!IK31KvRN?vc@gzQON5bcV-%&PZcUE-Y$J&#tUep#9q1;$L3d zTj||C`pvPsf7%V0IKJ8jcAVW+HUIs$1^SCE*K}Ca3#-LocP9N)EbH=(Oa<-LNr}8Y zki{|5^SE@_3j2vk+y?cG)6$};B&lU-M*;)1Pd^tRBEM6Bi5$2XEHdJOg;G1q z>DlEH*as&)^G7Rw;#>yu0Y1*+GF7m)s~qn)mzyN`M4t0Iw|r2S$Li>^?<*Jh46}HmLS~)|7asEGNaDAL z+`G)2o1^fL&dA3+z+F=D4t6R2jAV=;h_KB9ZdI>rsgW0x&h%@pIJ`y)y%FEjlC zsL^pU1m_m;SUH_*<8aLx@49W5KIQYATdyM43>&j9A zaF~R{a0w(ixrRgh3dX;=GxL1H1#y(|jVh1-9&>)01m(-SUr=ixlDMwFzyWH_@()P1 z5M6R|dQz@Vv9Nr8HNB6#mjP)wsWr{exIHG#^4QV*m^ML4HAiZ!tI3Y@1)BPh*;SVQ z#WVQ2@@2*C1yM`>+@D~URe$o0YqoX*SNj>blcirpFj#$JGfp2MQnRU^9JiA;pLB!j zOma&m*iDQ0uC$TNVjQq55!;1z@V=-lV6_IbuN@yWXx4m8?5i#|^R+A)?GM|Lne1`p z{U6}z9gYV0>@)QXv~%}yiPtAT#kl>>z#JMvS7XMZ!56;z$&blffuX=lH>I`Cx%K?e zpj+mj$z8ptUnP4VbQ0D=1a1_UQRIh9wD$pak`1%mCg)zR-T;hEWv1?hayyeh|TgW-eJ6l>S}HX(m9m~%X~+{cHNKH?wW$kXP7+vRw35T zo3aOHZ0=y~gWM6N*CN>Pl2P%4f>8Ub&)?EH(wtZd+*b`7`fjjN2zJ!Wb0#$E< z^S%}&dz7FjZN16Cn#nlK%vGH&)6#9z$r<7=7rflpkv`O@AQte`$zsy>519SZ&hx1s zQmsqvIQMD#qIyKk9=t)-`9aUSnl0;SZ4yVlX|t&^K!DyH^KiaQJM+sygOgP-hel9qi`81%?0F&lLL_&RW+*>$e&_UA`SRa~RA(rkRbBzsLe zl{ep+iR)#uoQ>G37wJA`*A>0_=p;WjJoZ;GZ~%YX38-Y`LQ9@8h6=XuWN|QJ`ZWit zb2%^{`(@O^b<&=m@aJofD*X3%z2>IpHJFu4_~)WSof88uT~6AKdL(j`eh1ro@MEqy zD%5sAKH`R51kT;(X?Myq*7`f@*z^ z#!R2x&$Z6Vb4B4IElGW^`>@RP61u6k*u#Zk{2z>yM@Hw!i*kpA%uJKCn%+@7_x~y` zSQl^l$@(0f(nr>|EcS=$#LX9q66#f#7=OqwjtiGjbtYJPn~4Q;hJUZ!zuKJZyqzu# zp^3R9KAK*LCBc%=pt>u+9xLzij;dT)b>}`K3NjMhs!yQ>gGJ7@EbvU@T1THK0`xc@} ztPO!WzWn~{u0lAEiPkPrQg8`rZapvNX#&Ij+Bk@4Y|ht;~@PU;diE z_sPh4*wiQYSSfVziEc6dX!$IA8usU^%?aqd>k}Tw9^%`!Cr%jqBW+>m{fXCbFj-p4 zHNMK+MHi~zG~YfiRVo|wg8u8#T!dTa@ia&ke?^uhC(DD} zWyQ0GZic5ttOYaloNo^}Xx(Qk)s&aHx%ttbUQ;bU`*og_GI*w28(mTtc3~d!u+&o> zB=rVxBW%&NQn&^?>!!D?OAoso>uqi@r~UQEH{#lGG8gqo^7-EeX0R1$Aa-pqdo9l% zImw}r7s$XZG=?5OgQ?*d@ngjTQ11*g=-#jxY=(2!M|nX>s0ky2(#>M(!-!L(%&`JZut2gm^cFWv zT1cQ-EALQPZ8?7z-V;?CNzka^=78u1jFr_f+-lIu+Y43Uf8$FI_A>(+oQQ5 zUr-_C(r#XSvqD=+XUxHhGbRp)tUs5B#_#H&;%MmsDK`;1`$V3(3Q6`vC4CsGlksHI zZ<=oi^OX|t!x@T%Wf1#>Kpw!WTy!-6zDN&sHz@L-jG9?)kYFyAQZB9|9fTnjbHspZ zESGpNH*RoW{DK_ZjYTjOOU2Y0!|P7GwvPdIk7P(s8mbG=tV`aUOH6$m)65s%t_A7f z1-zC@iGwGz)W+{-#KA!@iqmLJ5!o1u&?l3KY(Ee-6AQprZoY~C^D`FrHkB+ap29)A z&OZJ#X)-@g++W#vhyFBL!UU|^*rA_s%cbcwglSr}35bYvP0h3c##C+q6 z&{H{=j_!Gk10i!&u54IFk_dq%HbNedkr9U<;ea6D%tRdEUH2l4=@3N+ID%|>aSp{{Y0?lePc= literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_comics.png b/images/shortcuts_group_comics.png new file mode 100644 index 0000000000000000000000000000000000000000..b0c44cd98576820f55508a866011c4043384db2e GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^{2@)Z;PBq3c)UjmAa;4;HBn4T7r-89mOXEAUzvIp^Lv=U^p}z$EmO=LsXbn$q8n z%W14ertu7!{~S7>F{fnBqaJ_fHRHmmzh@_6V=e< z@fIp|@Ujq3*rvET`Oq@SS!MDLI~DX<7iAw=DarL}VdF}U(;P006E-)_NO;7^VZiXG W(cJ%`KX(|=2MnIBelF{r5}E+Dv0@AW literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_folders.png b/images/shortcuts_group_folders.png new file mode 100644 index 0000000000000000000000000000000000000000..968e5a20d07765c0d6ea94fc0c491f82e3aa6a84 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^{2^)r^Ln>}1B}ix-;83!$wf(=?JLmqsxf65FwlEmBJ>EW3 zCOWa9Q)ss1EdB{AzcU;)lUE6Te^Bw&^G0R{MmC0=ZoWM0i}l_>qZmA0{an^LB{Ts5 Dm98>U literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_general.png b/images/shortcuts_group_general.png new file mode 100644 index 0000000000000000000000000000000000000000..81c8317a07480d5b651c0795b06e0b5c49bca34a GIT binary patch literal 319 zcmV-F0l@x=P)StlgkTj<7+q0gR9l>PXL$>o}KMvP_Jhe=qT_A@e-H$#kT7+qQ=l;}u{elSl{B zUHqDaKT)#$118{;%-U!q!*)nAl>|XlYylb6;d_9(07q(6J498Mi{lx*sDKw~q}Ix; z5$CE4kF74MV&tV@tP*^R){7iLIh@=k3(nPO!I*VKC8sKn6&Q2fm47EdFMzu-)^rma zlv1cT3CI^ivyf%mLxW$--&;H<(S^nBrDMHX$_h?P_KyHZB((4LKdD=s002ovPDHLkV1lZ?gg5{I literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_libraries.png b/images/shortcuts_group_libraries.png new file mode 100644 index 0000000000000000000000000000000000000000..7c7f9b197c9502858cb43c32c238142fec67a6b3 GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^{2}1B`jbtXyWkqKmUJ8)}4K|*2==FX2DBlHYV9m zew9C=UbD=M+ivniMziUG_tTR8+82EEF+I!QapiM^mL`wF0S3#*{9Bhv-DLrq$l&Sf K=d#Wzp$PyRxi$0v literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_mglass.png b/images/shortcuts_group_mglass.png new file mode 100644 index 0000000000000000000000000000000000000000..4d1dde7af6b24edca99c84d8ed359037f72a497f GIT binary patch literal 351 zcmV-l0igbgP)dg2b2h;!zYm=v6@7p zU@k4VWR+kyRw%|^S5zapqSUw?j-k|-MuLLZ*cOMX*H6~a`?mORa}`_oMSiSRx?BLU zj8h#o#u8qSwz%NaEkE8i_iq1uW0q9%RpgI>=y3A``ol~3%cZQDx_1bZBB xz?39cDi9?bV5SD!JHP%ODBQsNWP}v{M83h0U002ovPDHLkV1n)zjd=h7 literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_page.png b/images/shortcuts_group_page.png new file mode 100644 index 0000000000000000000000000000000000000000..a482cebbe2339e4c669cad19908bb42ad2cc01bc GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^{2}1B`jbtP%5^uwf(?>c~*q6fq|J}(oMmyftI)XfaWoHy85}S Ib4q9e05~f$rvLx| literal 0 HcmV?d00001 diff --git a/images/shortcuts_group_reading.png b/images/shortcuts_group_reading.png new file mode 100644 index 0000000000000000000000000000000000000000..fd520f183455508a70b05574f69c2f345a2da88a GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^{2}1B`jbtP%5^uwf(k7RCwCNQp*j3KoDiAzz(DY=m3tK z)C$xJ)Doz`SOHi8dg6#3KnG|Cl;C@0HkpjXE0etJ@^;>Q34*1}St8H#GmbqFEBXyQ zfTC%d@kb01oogWalZ?U(0#y76m9SMpIu$?$93?Yt1(fhVOqp>ZG020r1kroErMUOP zwWgJfnXg7ziLe#HApFg=P*S`#(L&R$>#`EoL_&h#_&tTw^y zof&B2)T12;Ge3npsku;?F}O3)Yt`$VvG1L)YVHr?4mW0ybiT_b#$a*#3NQfev`7kg S=w>|t0000 ActionsGroupsModel::getActions(const QModelIndex &mi) +{ + if(mi.isValid()) + return groups[mi.row()].getActions(); + return QList(); +} + +//------------------------------------------------------------------- + +ActionsGroup::ActionsGroup(const QString &name, const QIcon &icon, QList &actions) + :name(name), icon(icon), actions(actions) +{ + +} + +QString ActionsGroup::getName() const +{ + return name; +} + +QIcon ActionsGroup::getIcon() const +{ + return icon; +} + +QList ActionsGroup::getActions() const +{ + return actions; +} diff --git a/shortcuts_management/actions_groups_model.h b/shortcuts_management/actions_groups_model.h new file mode 100644 index 00000000..91fb5a7c --- /dev/null +++ b/shortcuts_management/actions_groups_model.h @@ -0,0 +1,44 @@ +#ifndef ACTIONS_GROUPS_MODEL_H +#define ACTIONS_GROUPS_MODEL_H + +#include +#include + +class QAction; + +class ActionsGroup +{ +public: + ActionsGroup(const QString & name, const QIcon & icon, QList & actions); + QString getName() const; + QIcon getIcon() const; + QList getActions() const; +protected: + QString name; + QIcon icon; + QList actions; +}; + +class ActionsGroupsModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit ActionsGroupsModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QModelIndex parent(const QModelIndex &index) const; + + void addActionsGroup(const ActionsGroup & group); + QList getActions(const QModelIndex & mi); +signals: + +public slots: + +protected: + QList groups; +}; + +#endif // ACTIONS_GROUPS_MODEL_H diff --git a/shortcuts_management/actions_shortcuts_model.cpp b/shortcuts_management/actions_shortcuts_model.cpp new file mode 100644 index 00000000..ba9b98bc --- /dev/null +++ b/shortcuts_management/actions_shortcuts_model.cpp @@ -0,0 +1,106 @@ +#include "actions_shortcuts_model.h" +#include "shortcuts_manager.h" + +#include + +ActionsShortcutsModel::ActionsShortcutsModel(QObject *parent) : + QAbstractItemModel(parent) +{ + +} + +int ActionsShortcutsModel::rowCount(const QModelIndex &parent) const +{ + return actions.length(); +} + +int ActionsShortcutsModel::columnCount(const QModelIndex &parent) const +{ + return 3; +} + +QModelIndex ActionsShortcutsModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + return createIndex(row, column, actions[row]); +} + +Qt::ItemFlags ActionsShortcutsModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + if(index.column() == KEYS) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant ActionsShortcutsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DecorationRole && index.column() == ICON) + return QVariant(actions[index.row()]->icon()); + + if (role == Qt::TextAlignmentRole) + { + switch(index.column()) + { + case ICON: + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + case NAME: + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + case KEYS: + return QVariant(Qt::AlignRight | Qt::AlignVCenter); + } + } + + if(role == Qt::ForegroundRole && index.column() == KEYS && actions[index.row()]->shortcut().isEmpty()) + return QBrush(QColor("#AAAAAA")); + + if (role != Qt::DisplayRole) + return QVariant(); + + if (index.column() == NAME) + return QVariant(actions[index.row()]->toolTip()); + if (index.column() == KEYS) + { + QKeySequence ks = actions[index.row()]->shortcut(); + if(ks.isEmpty()) + return tr("None"); + return QVariant(ks.toString(QKeySequence::NativeText)); + } + + return QVariant(); +} + +bool ActionsShortcutsModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(index.column() == KEYS) + { + ShortcutsManager sm = ShortcutsManager::getShortcutsManager(); + if(sm.checkConflicts(value.toString(), actions[index.row()])) + emit conflict(value.toString()); + else + { + actions[index.row()]->setShortcut(value.toString()); + ShortcutsManager::getShortcutsManager().saveShortcut(actions[index.row()]); + return true; + } + } + return false; +} + +QModelIndex ActionsShortcutsModel::parent(const QModelIndex &index) const +{ + return QModelIndex(); +} + +void ActionsShortcutsModel::addActions(const QList actions) +{ + beginResetModel(); + this->actions = actions; + endResetModel(); +} diff --git a/shortcuts_management/actions_shortcuts_model.h b/shortcuts_management/actions_shortcuts_model.h new file mode 100644 index 00000000..03e3bde6 --- /dev/null +++ b/shortcuts_management/actions_shortcuts_model.h @@ -0,0 +1,38 @@ +#ifndef ACTIONS_SHORTCUTS_MODEL_H +#define ACTIONS_SHORTCUTS_MODEL_H + +#include + +class QAction; + +class ActionsShortcutsModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit ActionsShortcutsModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); + QModelIndex parent(const QModelIndex &index) const; + + void addActions(const QList actions); + Qt::ItemFlags flags(const QModelIndex &index) const; + + + enum Columns { + ICON = 0, + NAME, + KEYS + }; +signals: + void conflict(QString); +public slots: + +protected: + QList actions; +}; + +#endif // ACTIONS_SHORTCUTS_MODEL_H diff --git a/shortcuts_management/edit_shortcut_item_delegate.cpp b/shortcuts_management/edit_shortcut_item_delegate.cpp new file mode 100644 index 00000000..4c10b11a --- /dev/null +++ b/shortcuts_management/edit_shortcut_item_delegate.cpp @@ -0,0 +1,145 @@ +#include "edit_shortcut_item_delegate.h" + +#include + +EditShortcutItemDelegate::EditShortcutItemDelegate(QObject *parent) : + QItemDelegate(parent) +{ +} + +QWidget *EditShortcutItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + KeySequenceLineEdit * editor = new KeySequenceLineEdit(parent); + connect(editor,SIGNAL(editingFinished()),this,SLOT(closeShortcutEditor())); + return editor; +} + +void EditShortcutItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QString value = index.model()->data(index, Qt::DisplayRole).toString(); + + KeySequenceLineEdit * lineEdit = static_cast(editor); + lineEdit->setText(value); +} + +void EditShortcutItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + KeySequenceLineEdit *lineEdit = static_cast(editor); + + model->setData(index, lineEdit->text(), Qt::EditRole); +} + +void EditShortcutItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &mi) const +{ + editor->setGeometry(option.rect); +} + +bool EditShortcutItemDelegate::eventFilter(QObject* editor, QEvent* event) +{ + if(event->type()==QEvent::KeyPress) + return false; + return QItemDelegate::eventFilter(editor, event); +} + +void EditShortcutItemDelegate::closeShortcutEditor() +{ + emit commitData(static_cast(sender())); + emit closeEditor(static_cast(sender()),QAbstractItemDelegate::NoHint); +} + +//TODO uncoment commented code for enabling concatenated shortcuts +KeySequenceLineEdit::KeySequenceLineEdit(QWidget *parent) + :QLineEdit(parent)//,numKeys(0) +{ + //keys[0] = keys[1] = keys[2] = keys[3] = 0; + setAlignment(Qt::AlignRight); + + QPixmap clearPixmap(":/images/clear_shortcut.png"); + QPixmap acceptPixmap(":/images/accept_shortcut.png"); + + clearButton = new QToolButton(this); + acceptButton = new QToolButton(this); + QString buttonsStyle = "QToolButton { border: none; padding: 0px; }"; + + clearButton->setIcon(QIcon(clearPixmap)); + clearButton->setIconSize(clearPixmap.size()); + clearButton->setCursor(Qt::ArrowCursor); + clearButton->setStyleSheet(buttonsStyle); + + acceptButton->setIcon(QIcon(acceptPixmap)); + acceptButton->setIconSize(acceptPixmap.size()); + acceptButton->setCursor(Qt::ArrowCursor); + acceptButton->setStyleSheet(buttonsStyle); + + connect(clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(acceptButton, SIGNAL(clicked()), this, SIGNAL(editingFinished())); +} + +void KeySequenceLineEdit::resizeEvent(QResizeEvent * e) +{ + QSize szClear = clearButton->sizeHint(); + //int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + int leftMargin = style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + int topMargin = style()->pixelMetric(QStyle::PM_LayoutTopMargin); + clearButton->move(0 + leftMargin,(e->size().height()-19)/2); //16 is the icon height+1blank pixel + + acceptButton->move( leftMargin + szClear.width(),(e->size().height()-19)/2); + +} + +void KeySequenceLineEdit::keyPressEvent(QKeyEvent * e) +{ + int key = e->key(); + + + //if ( numKeys > 3 || + if ( key == Qt::Key_Control || + key == Qt::Key_Shift || + key == Qt::Key_Meta || + key == Qt::Key_Alt ) + return; + + key |= translateModifiers(e->modifiers(), e->text()); + + /*switch (numKeys) { + case 0: + keys[0] = nextKey; + break; + case 1: + keys[1] = nextKey; + break; + case 2: + keys[2] = nextKey; + break; + case 3: + keys[3] = nextKey; + break; + default: + break; + }*/ + //numKeys++; + QKeySequence keySequence = QKeySequence(key); + setText(keySequence.toString(QKeySequence::NativeText)); + e->accept(); +} + +int KeySequenceLineEdit::translateModifiers(Qt::KeyboardModifiers state, + const QString &text) +{ + int result = 0; + // The shift modifier only counts when it is not used to type a symbol + // that is only reachable using the shift key anyway + if ((state & Qt::ShiftModifier) && (text.size() == 0 + || !text.at(0).isPrint() + || text.at(0).isLetterOrNumber() + || text.at(0).isSpace())) + result |= Qt::SHIFT; + if (state & Qt::ControlModifier) + result |= Qt::CTRL; + if (state & Qt::MetaModifier) + result |= Qt::META; + if (state & Qt::AltModifier) + result |= Qt::ALT; + return result; +} + diff --git a/shortcuts_management/edit_shortcut_item_delegate.h b/shortcuts_management/edit_shortcut_item_delegate.h new file mode 100644 index 00000000..7cc1e4e8 --- /dev/null +++ b/shortcuts_management/edit_shortcut_item_delegate.h @@ -0,0 +1,48 @@ +#ifndef EDIT_SHORTCUT_ITEM_DELEGATE_H +#define EDIT_SHORTCUT_ITEM_DELEGATE_H + +#include +#include +#include +#include +#include + +class KeySequenceLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit KeySequenceLineEdit(QWidget *parent = 0); + +protected: + //int numKeys; + //int keys[4]; + void keyPressEvent(QKeyEvent *); + int translateModifiers(Qt::KeyboardModifiers state, const QString &text); + void resizeEvent(QResizeEvent *); + +private: + QToolButton *clearButton; + QToolButton *acceptButton; +}; + +class EditShortcutItemDelegate : public QItemDelegate +{ + Q_OBJECT +public: + explicit EditShortcutItemDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & mi) const; + bool eventFilter(QObject *editor, QEvent *event); +signals: + +public slots: + void closeShortcutEditor(); + +}; + +#endif // EDIT_SHORTCUT_ITEM_DELEGATE_H diff --git a/shortcuts_management/edit_shortcuts_dialog.cpp b/shortcuts_management/edit_shortcuts_dialog.cpp new file mode 100644 index 00000000..46dea7a6 --- /dev/null +++ b/shortcuts_management/edit_shortcuts_dialog.cpp @@ -0,0 +1,95 @@ +#include "edit_shortcuts_dialog.h" + +#include "actions_groups_model.h" +#include "actions_shortcuts_model.h" +#include "edit_shortcut_item_delegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "QsLog.h" + +EditShortcutsDialog::EditShortcutsDialog(QWidget *parent) : + QDialog(parent) +{ + QPushButton * resetButton = new QPushButton(tr("Restore defaults"),this); + QLabel * infoLabel = new QLabel(tr("To change a shortcut, double click in the key combination and type the new keys.")); + QVBoxLayout * layout = new QVBoxLayout(this); + QSplitter * splitter = new QSplitter(this); + actionsGroupsListView = new QListView(this); + + actionsTableView = new QTableView(this); + actionsTableView->verticalHeader()->setHidden(true); + actionsTableView->horizontalHeader()->setHidden(true); + splitter->addWidget(actionsGroupsListView); + splitter->addWidget(actionsTableView); + splitter->setStretchFactor(1,1); + splitter->setSizes(QList() << 200 << 400); + + layout->addWidget(infoLabel,0); + layout->addWidget(splitter,1); + layout->addWidget(resetButton,0,Qt::AlignRight); + + setLayout(layout); + + groupsModel = new ActionsGroupsModel(); + actionsModel = new ActionsShortcutsModel(); + actionsGroupsListView->setModel(groupsModel); + actionsGroupsListView->setFocus(); + actionsTableView->setModel(actionsModel); + actionsTableView->setColumnWidth(0,30); + actionsTableView->setColumnWidth(1,360); + //actionsTableView->horizontalHeader()->sectionResizeMode(QHeaderView::Custom); + actionsTableView->horizontalHeader()->setStretchLastSection(true); + actionsTableView->setSelectionBehavior(QAbstractItemView::SelectRows); + actionsTableView->setShowGrid(false); + actionsTableView->setItemDelegateForColumn(ActionsShortcutsModel::KEYS,new EditShortcutItemDelegate(this)); + actionsTableView->installEventFilter(this); + /*actionsTableView->setStyleSheet("QTableView {outline: 0px;}" + "QTableView::item {outline: 0px;}"); + "QTableView {border:0px;}" + "QTableView::item:selected {outline: 0px; border: 0px;}" + "");*/ + + + connect(resetButton,SIGNAL(clicked()),this,SLOT(resetToDefaults())); + connect(actionsGroupsListView->selectionModel(),SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(loadShortcuts(QModelIndex,QModelIndex))); //clicked(QModelIndex) doesn't work :S + connect(actionsModel,SIGNAL(conflict(QString)),this,SLOT(processConflict(QString))); + +#ifdef Q_OS_MAC + setFixedSize(760,500); +#else + setFixedSize(804,500); //extra width for modifiers +#endif + setWindowTitle(tr("Shortcuts settings")); + + setModal(true); +} + +void EditShortcutsDialog::addActionsGroup(const QString &name, const QIcon &ico, QList &group) +{ + groupsModel->addActionsGroup(ActionsGroup(name,ico,group)); + if(actionsTableView->model()->rowCount()==0)//first group added + actionsGroupsListView->selectionModel()->select(groupsModel->index(0,0),QItemSelectionModel::Select); +} + +void EditShortcutsDialog::resetToDefaults() +{ + +} + +void EditShortcutsDialog::loadShortcuts(const QModelIndex &mi,const QModelIndex &mi2) +{ + actionsModel->addActions(groupsModel->getActions(mi)); +} + +void EditShortcutsDialog::processConflict(const QString &shortcutInConflict) +{ + QMessageBox::warning(this,tr("Shortcut in use"), QString(tr("The shortcut \"%1\" is already assigned to other function")).arg(shortcutInConflict)); +} diff --git a/shortcuts_management/edit_shortcuts_dialog.h b/shortcuts_management/edit_shortcuts_dialog.h new file mode 100644 index 00000000..e0debf98 --- /dev/null +++ b/shortcuts_management/edit_shortcuts_dialog.h @@ -0,0 +1,33 @@ +#ifndef EDIT_SHORTCUTS_DIALOG_H +#define EDIT_SHORTCUTS_DIALOG_H + +#include +#include + +class QListView; +class QTableView; + +class ActionsGroupsModel; +class ActionsShortcutsModel; + +class EditShortcutsDialog : public QDialog +{ + Q_OBJECT +public: + explicit EditShortcutsDialog(QWidget * parent = 0); + void addActionsGroup(const QString & name, const QIcon & ico, QList & group); +signals: + +public slots: + void resetToDefaults(); + void loadShortcuts(const QModelIndex & mi,const QModelIndex &mi2); + void processConflict(const QString & shortcutInConflict); + +protected: + QListView * actionsGroupsListView; + QTableView * actionsTableView; + ActionsGroupsModel * groupsModel; + ActionsShortcutsModel * actionsModel; +}; + +#endif // EDIT_SHORTCUTS_DIALOG_H diff --git a/shortcuts_management/shortcuts_management.pri b/shortcuts_management/shortcuts_management.pri new file mode 100644 index 00000000..d12f8fa0 --- /dev/null +++ b/shortcuts_management/shortcuts_management.pri @@ -0,0 +1,16 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + $$PWD/edit_shortcuts_dialog.h \ + $$PWD/actions_groups_model.h \ + $$PWD/actions_shortcuts_model.h \ + $$PWD/edit_shortcut_item_delegate.h \ + $$PWD/shortcuts_manager.h + +SOURCES += \ + $$PWD/edit_shortcuts_dialog.cpp \ + $$PWD/actions_groups_model.cpp \ + $$PWD/actions_shortcuts_model.cpp \ + $$PWD/edit_shortcut_item_delegate.cpp \ + $$PWD/shortcuts_manager.cpp diff --git a/shortcuts_management/shortcuts_manager.cpp b/shortcuts_management/shortcuts_manager.cpp new file mode 100644 index 00000000..df8d253d --- /dev/null +++ b/shortcuts_management/shortcuts_manager.cpp @@ -0,0 +1,112 @@ +#include "shortcuts_manager.h" + +#include +#include +#include "yacreader_global.h" + +ShortcutsManager::ShortcutsManager() +{ + initDefaultShorcuts(); +} + +void ShortcutsManager::initDefaultShorcuts() +{ +#ifdef YACREADER_LIBRARY + //ACTIONS + defaultShorcuts.insert(CREATE_LIBRARY_ACTION_YL,Qt::Key_A); + defaultShorcuts.insert(OPEN_LIBRARY_ACTION_YL,Qt::Key_O); + defaultShorcuts.insert(UPDATE_LIBRARY_ACTION_YL,Qt::Key_U); + defaultShorcuts.insert(RENAME_LIBRARY_ACTION_YL,Qt::Key_R); + defaultShorcuts.insert(OPEN_COMIC_ACTION_YL,Qt::Key_Return); + defaultShorcuts.insert(SHOW_HIDE_MARKS_ACTION_YL,Qt::Key_M); + defaultShorcuts.insert(TOGGLE_FULL_SCREEN_ACTION_YL,Qt::Key_F); + defaultShorcuts.insert(HELP_ABOUT_ACTION_YL,Qt::Key_F1); + defaultShorcuts.insert(SET_ROOT_INDEX_ACTION_YL,Qt::Key_0); + defaultShorcuts.insert(EXPAND_ALL_NODES_ACTION_YL,Qt::Key_Plus); + defaultShorcuts.insert(COLAPSE_ALL_NODES_ACTION_YL,Qt::Key_Minus); + defaultShorcuts.insert(OPTIONS_ACTION_YL,Qt::Key_C); + defaultShorcuts.insert(SERVER_CONFIG_ACTION_YL,Qt::Key_S); + defaultShorcuts.insert(TOGGLE_COMICS_VIEW_ACTION_YL,Qt::Key_V); + + //COMMANDS (used in keypressevent) +#else + defaultShorcuts.insert(OPEN_ACTION_Y, Qt::Key_O); + defaultShorcuts.insert(OPEN_FOLDER_ACTION_Y, Qt::CTRL | Qt::Key_O); + defaultShorcuts.insert(OPEN_PREVIOUS_COMIC_ACTION_Y, Qt::CTRL | Qt::Key_Left); + defaultShorcuts.insert(OPEN_NEXT_COMIC_ACTION_Y, Qt::CTRL | Qt::Key_Right); + defaultShorcuts.insert(PREV_ACTION_Y, Qt::Key_Left); + defaultShorcuts.insert(NEXT_ACTION_Y, Qt::Key_Right); + defaultShorcuts.insert(LEFT_ROTATION_ACTION_Y, Qt::Key_L); + defaultShorcuts.insert(RIGHT_ROTATION_ACTION_Y, Qt::Key_R); + defaultShorcuts.insert(DOUBLE_PAGE_ACTION_Y, Qt::Key_D); + defaultShorcuts.insert(GO_TO_PAGE_ACTION_Y, Qt::Key_G); + defaultShorcuts.insert(OPTIONS_ACTION_Y, Qt::Key_C); + defaultShorcuts.insert(HELP_ABOUT_ACTION_Y, Qt::Key_F1); + defaultShorcuts.insert(SHOW_MAGNIFYING_GLASS_ACTION_Y, Qt::Key_Z); + defaultShorcuts.insert(SET_BOOKMARK_ACTION_Y, Qt::CTRL | Qt::Key_M); + defaultShorcuts.insert(SHOW_BOOKMARKS_ACTION_Y, Qt::Key_M); + defaultShorcuts.insert(SHOW_INFO_ACTION_Y, Qt::Key_I); + defaultShorcuts.insert(CLOSE_ACTION_Y, Qt::Key_Escape); + defaultShorcuts.insert(SHOW_DICTIONARY_ACTION_Y, Qt::Key_T); + defaultShorcuts.insert(ALWAYS_ON_TOP_ACTION_Y, Qt::Key_Q); //deprecated + defaultShorcuts.insert(ADJUST_TO_FULL_SIZE_ACTION_Y, Qt::Key_W); + defaultShorcuts.insert(SHOW_FLOW_ACTION_Y, Qt::Key_S); + + //main_window_viewer + defaultShorcuts.insert(TOGGLE_FULL_SCREEN_ACTION_Y, Qt::Key_F); + defaultShorcuts.insert(TOGGLE_TOOL_BARS_ACTION_Y, Qt::Key_H); + defaultShorcuts.insert(CHANGE_FIT_ACTION_Y, Qt::Key_A); + //viewer + defaultShorcuts.insert(AUTO_SCROLL_FORWARD_ACTION_Y, Qt::Key_Space); + defaultShorcuts.insert(AUTO_SCROLL_BACKWARD_ACTION_Y, Qt::Key_B); + defaultShorcuts.insert(MOVE_DOWN_ACTION_Y, Qt::Key_Down); + defaultShorcuts.insert(MOVE_UP_ACTION_Y, Qt::Key_Up); + defaultShorcuts.insert(GO_TO_FIRST_PAGE_ACTION_Y, Qt::Key_Home); + defaultShorcuts.insert(GO_TO_LAST_PAGE_ACTION_Y, Qt::Key_End); + //mglass + defaultShorcuts.insert(SIZE_UP_MGLASS_ACTION_Y, Qt::Key_Plus); + defaultShorcuts.insert(SIZE_DOWN_MGLASS_ACTION_Y, Qt::Key_Minus); + defaultShorcuts.insert(ZOOM_IN_MGLASS_ACTION_Y, Qt::Key_Asterisk); + defaultShorcuts.insert(ZOOM_OUT_MGLASS_ACTION_Y, Qt::Key_Underscore); + +#endif + +} + +void ShortcutsManager::resetToDefaults() +{ + //TODO reset to defaults +} + +QString ShortcutsManager::getShortcut(const QString &name) +{ + QSettings s(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); + s.beginGroup("shortcuts"); + + return s.value(name,defaultShorcuts.value(name)).toString(); +} + +void ShortcutsManager::saveShortcut(QAction *action) +{ + QSettings s(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); + s.beginGroup("shortcuts"); + + return s.setValue(action->data().toString() , action->shortcut().toString()); +} + +void ShortcutsManager::registerActions(const QList &a) +{ + actions = a; +} + +bool ShortcutsManager::checkConflicts(const QKeySequence & shortcut, const QAction *dest) +{ + foreach(QAction * action, actions) + { + if(action != dest) //if the same shortcut is setted there is no conflict + if(action->shortcut() == shortcut) + return true; + } + + return false; +} diff --git a/shortcuts_management/shortcuts_manager.h b/shortcuts_management/shortcuts_manager.h new file mode 100644 index 00000000..c6e3eae5 --- /dev/null +++ b/shortcuts_management/shortcuts_manager.h @@ -0,0 +1,127 @@ +#ifndef SHORTCUTS_MANAGER_H +#define SHORTCUTS_MANAGER_H + +#include +#include +#include +#include + + +class QAction; + +//QAction: used setData() and data() for storing (userData) an identifier for each QAction. This value is ussed in QSettings + +class ShortcutsManager +{ +private: + ShortcutsManager(); + QMap defaultShorcuts; + QList actions; //all actions registered, used for checking conflicts + + void initDefaultShorcuts(); +public: + static ShortcutsManager & getShortcutsManager() + { + static ShortcutsManager manager; + return manager; + } + + void resetToDefaults(); + QString getShortcut(const QString & name); + void saveShortcut(QAction * action); + void registerActions(const QList & actions); + bool checkConflicts(const QKeySequence &shortcut, const QAction *dest); +}; + +//ACTION NAMES YACReaderLibrary +#define BACK_ACTION_YL "BACK_ACTION_YL" +#define FORWARD_ACTION_YL "FORWARD_ACTION_YL" +#define CREATE_LIBRARY_ACTION_YL "CREATE_LIBRARY_ACTION_YL" +#define OPEN_LIBRARY_ACTION_YL "OPEN_LIBRARY_ACTION_YL" +#define EXPORT_COMICS_INFO_ACTION_YL "EXPORT_COMICS_INFO_ACTION_YL" +#define IMPORT_COMICS_INFO_ACTION_YL "IMPORT_COMICS_INFO_ACTION_YL" +#define EXPORT_LIBRARY_ACTION_YL "EXPORT_LIBRARY_ACTION_YL" +#define IMPORT_LIBRARY_ACTION_YL "IMPORT_LIBRARY_ACTION_YL" +#define UPDATE_LIBRARY_ACTION_YL "UPDATE_LIBRARY_ACTION_YL" +#define RENAME_LIBRARY_ACTION_YL "RENAME_LIBRARY_ACTION_YL" +#define REMOVE_LIBRARY_ACTION_YL "REMOVE_LIBRARY_ACTION_YL" +#define OPEN_COMIC_ACTION_YL "OPEN_COMIC_ACTION_YL" +#define SET_AS_READ_ACTION_YL "SET_AS_READ_ACTION_YL" +#define SET_AS_NON_READ_ACTION_YL "SET_AS_NON_READ_ACTION_YL" +#define SHOW_HIDE_MARKS_ACTION_YL "SHOW_HIDE_MARKS_ACTION_YL" +#define TOGGLE_FULL_SCREEN_ACTION_YL "TOGGLE_FULL_SCREEN_ACTION_YL" +#define HELP_ABOUT_ACTION_YL "HELP_ABOUT_ACTION_YL" +#define SET_ROOT_INDEX_ACTION_YL "SET_ROOT_INDEX_ACTION_YL" +#define EXPAND_ALL_NODES_ACTION_YL "EXPAND_ALL_NODES_ACTION_YL" +#define COLAPSE_ALL_NODES_ACTION_YL "COLAPSE_ALL_NODES_ACTION_YL" +#define OPTIONS_ACTION_YL "OPTIONS_ACTION_YL" +#define SERVER_CONFIG_ACTION_YL "SERVER_CONFIG_ACTION_YL" +#define TOGGLE_COMICS_VIEW_ACTION_YL "TOGGLE_COMICS_VIEW_ACTION_YL" +#define OPEN_CONTAINING_FOLDER_ACTION_YL "OPEN_CONTAINING_FOLDER_ACTION_YL" +#define SET_FOLDER_AS_NOT_COMPLETED_ACTION_YL "SET_FOLDER_AS_NOT_COMPLETED_ACTION_YL" +#define SET_FOLDER_AS_COMPLETED_ACTION_YL "SET_FOLDER_AS_COMPLETED_ACTION_YL" +#define SET_FOLDER_AS_READ_ACTION_YL "SET_FOLDER_AS_READ_ACTION_YL" +#define SET_FOLDER_AS_UNREAD_ACTION_YL "SET_FOLDER_AS_UNREAD_ACTION_YL" +#define OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL "OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL" +#define RESET_COMIC_RATING_ACTION_YL "RESET_COMIC_RATING_ACTION_YL" +#define SELECT_ALL_COMICS_ACTION_YL "SELECT_ALL_COMICS_ACTION_YL" +#define EDIT_SELECTED_COMICS_ACTION_YL "EDIT_SELECTED_COMICS_ACTION_YL" +#define ASIGN_ORDER_ACTION_YL "ASIGN_ORDER_ACTION_YL" +#define FORCE_COVER_EXTRACTED_ACTION_YL "FORCE_COVER_EXTRACTED_ACTION_YL" +#define DELETE_COMICS_ACTION_YL "DELETE_COMICS_ACTION_YL" +#define HIDE_COMIC_VIEW_ACTION_YL "HIDE_COMIC_VIEW_ACTION_YL" +#define GET_INFO_ACTION_YL "GET_INFO_ACTION_YL" +#define SHOW_EDIT_SHORTCUTS_ACTION_YL "SHOW_EDIT_SHORTCUTS_ACTION_YL" + +//COMMANDS YACReaderLibrary + + +//ACTION NAMES YACReader +#define OPEN_ACTION_Y "OPEN_ACTION_Y" +#define OPEN_FOLDER_ACTION_Y "OPEN_FOLDER_ACTION_Y" +#define SAVE_IMAGE_ACTION_Y "SAVE_IMAGE_ACTION_Y" +#define OPEN_PREVIOUS_COMIC_ACTION_Y "OPEN_PREVIOUS_COMIC_ACTION_Y" +#define OPEN_NEXT_COMIC_ACTION_Y "OPEN_NEXT_COMIC_ACTION_Y" +#define PREV_ACTION_Y "PREV_ACTION_Y" +#define NEXT_ACTION_Y "NEXT_ACTION_Y" +#define ADJUST_HEIGHT_ACTION_Y "ADJUST_HEIGHT_Y" +#define ADJUST_WIDTH_ACTION_Y "ADJUST_WIDTH_Y" +#define LEFT_ROTATION_ACTION_Y "LEFT_ROTATION_ACTION_Y" +#define RIGHT_ROTATION_ACTION_Y "RIGHT_ROTATION_ACTION_Y" +#define DOUBLE_PAGE_ACTION_Y "DOUBLE_PAGE_ACTION_Y" +#define GO_TO_PAGE_ACTION_Y "GO_TO_PAGE_ACTION_Y" +#define OPTIONS_ACTION_Y "OPTIONS_ACTION_Y" +#define HELP_ABOUT_ACTION_Y "HELP_ABOUT_ACTION_Y" +#define SHOW_MAGNIFYING_GLASS_ACTION_Y "SHOW_MAGNIFYING_GLASS_ACTION_Y" +#define SET_BOOKMARK_ACTION_Y "SET_BOOKMARK_ACTION_Y" +#define SHOW_BOOKMARKS_ACTION_Y "SHOW_BOOKMARKS_ACTION_Y" +#define SHOW_SHORCUTS_ACTION_Y "SHOW_SHORCUTS_ACTION_Y" +#define SHOW_INFO_ACTION_Y "SHOW_INFO_ACTION_Y" +#define CLOSE_ACTION_Y "CLOSE_ACTION_Y" +#define SHOW_DICTIONARY_ACTION_Y "SHOW_DICTIONARY_ACTION_Y" +#define ALWAYS_ON_TOP_ACTION_Y "ALWAYS_ON_TOP_ACTION_Y" +#define ADJUST_TO_FULL_SIZE_ACTION_Y "ADJUST_TO_FULL_SIZE_ACTION_Y" +#define SHOW_FLOW_ACTION_Y "SHOW_FLOW_ACTION_Y" +#define SHOW_EDIT_SHORTCUTS_ACTION_Y "SHOW_EDIT_SHORTCUTS_ACTION_Y" + +//COMMANDS YACReader +//main_viewer_window +#define TOGGLE_FULL_SCREEN_ACTION_Y "TOGGLE_FULL_SCREEN_ACTION_Y" +#define TOGGLE_TOOL_BARS_ACTION_Y "TOGGLE_TOOL_BARS_ACTION_Y" +#define CHANGE_FIT_ACTION_Y "CHANGE_FIT_ACTION_Y" +//viewer +#define AUTO_SCROLL_FORWARD_ACTION_Y "AUTO_SCROLL_FORWARD_ACTION_Y" +#define AUTO_SCROLL_BACKWARD_ACTION_Y "AUTO_SCROLL_BACKWARD_ACTION_Y" +#define MOVE_DOWN_ACTION_Y "MOVE_DOWN_ACTION_Y" +#define MOVE_UP_ACTION_Y "MOVE_UP_ACTION_Y" +#define MOVE_LEFT_ACTION_Y "MOVE_LEFT_ACTION_Y" +#define MOVE_RIGHT_ACTION_Y "MOVE_RIGHT_ACTION_Y" +#define GO_TO_FIRST_PAGE_ACTION_Y "GO_TO_FIRST_PAGE_ACTION_Y" +#define GO_TO_LAST_PAGE_ACTION_Y "GO_TO_LAST_PAGE_ACTION_Y" +//mglass +#define SIZE_UP_MGLASS_ACTION_Y "SIZE_UP_MGLASS_ACTION_Y" +#define SIZE_DOWN_MGLASS_ACTION_Y "SIZE_DOWN_MGLASS_ACTION_Y" +#define ZOOM_IN_MGLASS_ACTION_Y "ZOOM_IN_MGLASS_ACTION_Y" +#define ZOOM_OUT_MGLASS_ACTION_Y "ZOOM_OUT_MGLASS_ACTION_Y" + +#endif // SHORTCUTS_MANAGER_H