#include "classic_comics_view.h" #include "yacreader_global.h" #include "QStackedWidget" #include "comic_flow_widget.h" #include "QsLog.h" #include "shortcuts_manager.h" #include "yacreader_table_view.h" #include "yacreader_tool_bar_stretch.h" ClassicComicsView::ClassicComicsView(QWidget *parent) : ComicsView(parent), searching(false) { auto 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----------------------------------------------------------------------- //--------------------------------------------------------------------------- // FORCE_ANGLE is not used here, because ComicFlowWidgetGL will use OpenGL ES in the future #ifndef NO_OPENGL if ((settings->value(USE_OPEN_GL).toBool() == true)) comicFlow = new ComicFlowWidgetGL(0); else comicFlow = new ComicFlowWidgetSW(0); #else comicFlow = new ComicFlowWidgetSW(0); #endif comicFlow->updateConfig(settings); comicFlow->setFocusPolicy(Qt::StrongFocus); comicFlow->setShowMarks(true); setFocusProxy(comicFlow); comicFlow->setFocus(Qt::OtherFocusReason); comicFlow->setContextMenuPolicy(Qt::CustomContextMenu); // layout----------------------------------------------- sVertical = new QSplitter(Qt::Vertical); // spliter derecha stack = new QStackedWidget; stack->addWidget(comicFlow); setupSearchingIcon(); stack->addWidget(searchingIcon); sVertical->addWidget(stack); comics = new QWidget; auto 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); tableView->setContextMenuPolicy(Qt::CustomContextMenu); tableView->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); // connections--------------------------------------------- connect(tableView, &QAbstractItemView::clicked, this, &ClassicComicsView::centerComicFlow); connect(tableView, &QAbstractItemView::doubleClicked, this, &ClassicComicsView::selectedComicForOpening); connect(comicFlow, &ComicFlowWidget::centerIndexChanged, this, &ClassicComicsView::updateTableView); connect(tableView, &YACReaderTableView::comicRated, this, &ComicsView::comicRated); connect(comicFlow, &ComicFlowWidget::selected, this, &ComicsView::selected); connect(tableView->horizontalHeader(), &QHeaderView::sectionMoved, this, &ClassicComicsView::saveTableHeadersStatus); connect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &ClassicComicsView::saveTableHeadersStatus); connect(comicFlow, &QWidget::customContextMenuRequested, this, &ClassicComicsView::requestedViewContextMenu); connect(tableView, &QWidget::customContextMenuRequested, this, &ClassicComicsView::requestedItemContextMenu); connect(tableView->horizontalHeader(), &QWidget::customContextMenuRequested, this, &ClassicComicsView::requestedHeaderContextMenu); layout->addWidget(sVertical); setLayout(layout); layout->setContentsMargins(0, 0, 0, 0); #ifdef Y_MAC_UI sVertical->setCollapsible(1, false); #endif if (settings->contains(COMICS_VIEW_FLOW_SPLITTER_STATUS)) { try { sVertical->restoreState(settings->value(COMICS_VIEW_FLOW_SPLITTER_STATUS).toByteArray()); } catch (...) { // do nothing } } // hide flow widgets hideFlowViewAction = new QAction(this); hideFlowViewAction->setText(tr("Hide comic flow")); hideFlowViewAction->setData(HIDE_COMIC_VIEW_ACTION_YL); hideFlowViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HIDE_COMIC_VIEW_ACTION_YL)); hideFlowViewAction->setIcon(QIcon(":/images/comics_view_toolbar/hideComicFlow.svg")); hideFlowViewAction->setCheckable(true); hideFlowViewAction->setChecked(false); connect(hideFlowViewAction, &QAction::toggled, this, &ClassicComicsView::hideComicFlow); } void ClassicComicsView::hideComicFlow(bool hide) { if (hide) { QList sizes; sizes.append(0); int total = sVertical->sizes().at(0) + sVertical->sizes().at(1); sizes.append(total); sVertical->setSizes(sizes); } else { QList sizes; int total = sVertical->sizes().at(0) + sVertical->sizes().at(1); sizes.append(2 * total / 3); sizes.append(total / 3); sVertical->setSizes(sizes); } } // the toolbar has to be populated void ClassicComicsView::setToolBar(QToolBar *toolBar) { static_cast(comics->layout())->insertWidget(0, toolBar); this->toolbar = toolBar; startSeparatorAction = toolBar->addSeparator(); toolBar->addAction(hideFlowViewAction); } void ClassicComicsView::setModel(ComicModel *model) { ComicsView::setModel(model); if (model == NULL) { comicFlow->clear(); } else { connect(model, &QAbstractItemModel::dataChanged, this, &ClassicComicsView::applyModelChanges, Qt::UniqueConnection); connect(model, &QAbstractItemModel::rowsRemoved, this, &ClassicComicsView::removeItemsFromFlow, Qt::UniqueConnection); connect(model, &QAbstractItemModel::rowsInserted, this, &ClassicComicsView::addItemsToFlow, Qt::UniqueConnection); // TODO: Missing method resortCovers? connect(model, &ComicModel::resortedIndexes, comicFlow, &ComicFlowWidget::resortCovers, Qt::UniqueConnection); connect(model, &ComicModel::newSelectedIndex, this, &ClassicComicsView::setCurrentIndex, Qt::UniqueConnection); tableView->setModel(model); if (model->rowCount() > 0) tableView->setCurrentIndex(model->index(0, 0)); QStringList paths = model->getPaths(model->getCurrentPath()); // TODO ComicsView: get currentpath from somewhere currentPath()); comicFlow->setImagePaths(paths); comicFlow->setMarks(model->getReadList()); bool loadDefaults = false; if (settings->contains(COMICS_VIEW_HEADERS)) { try { loadDefaults = !tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); } catch (...) { loadDefaults = true; } } else { loadDefaults = true; } if (loadDefaults) { // default columns and order for (int i = 0; i < tableView->horizontalHeader()->count(); i++) tableView->horizontalHeader()->hideSection(i); tableView->horizontalHeader()->showSection(ComicModel::Number); tableView->horizontalHeader()->showSection(ComicModel::Title); tableView->horizontalHeader()->showSection(ComicModel::FileName); tableView->horizontalHeader()->showSection(ComicModel::NumPages); tableView->horizontalHeader()->showSection(ComicModel::Size); tableView->horizontalHeader()->showSection(ComicModel::ReadColumn); tableView->horizontalHeader()->showSection(ComicModel::CurrentPage); tableView->horizontalHeader()->showSection(ComicModel::PublicationDate); tableView->horizontalHeader()->showSection(ComicModel::Rating); tableView->horizontalHeader()->moveSection(ComicModel::CurrentPage, 3); tableView->horizontalHeader()->moveSection(ComicModel::Rating, 12); tableView->horizontalHeader()->moveSection(ComicModel::Size, 5); } // make sure that columns without title are hidden for (int i = 0; i < tableView->horizontalHeader()->count(); i++) { auto title = tableView->model()->headerData(i, Qt::Horizontal).toString(); if (title.isEmpty()) { tableView->horizontalHeader()->hideSection(i); } } tableView->resizeColumnsToContents(); tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); tableView->horizontalHeader()->setSectionsMovable(true); tableView->horizontalHeader()->setStretchLastSection(true); } } void ClassicComicsView::setCurrentIndex(const QModelIndex &index) { tableView->setCurrentIndex(index); centerComicFlow(index); } QModelIndex ClassicComicsView::currentIndex() { return tableView->currentIndex(); } QItemSelectionModel *ClassicComicsView::selectionModel() { return tableView->selectionModel(); } void ClassicComicsView::scrollTo(const QModelIndex &mi, QAbstractItemView::ScrollHint hint) { Q_UNUSED(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::enableFilterMode(bool enabled) { if (enabled) { comicFlow->clear(); if (previousSplitterStatus.isEmpty()) previousSplitterStatus = sVertical->saveState(); sVertical->setSizes(QList() << 100 << 10000000); showSearchingIcon(); } else { hideSearchingIcon(); sVertical->restoreState(previousSplitterStatus); previousSplitterStatus.clear(); } // sVertical->setCollapsible(0,!enabled); searching = enabled; } void ClassicComicsView::selectIndex(int index) { tableView->selectRow(index); } void ClassicComicsView::updateCurrentComicView() { } void ClassicComicsView::focusComicsNavigation(Qt::FocusReason reason) { const bool comicFlowVisible = stack->currentWidget() == comicFlow && sVertical->sizes().constFirst() != 0; if (comicFlowVisible) comicFlow->setFocus(reason); else // Let the user navigate the table. tableView->setFocus(reason); } void ClassicComicsView::selectAll() { tableView->selectAll(); } void ClassicComicsView::selectedComicForOpening(const QModelIndex &mi) { emit selected(mi.row()); } void ClassicComicsView::requestedViewContextMenu(const QPoint &point) { emit customContextMenuViewRequested(comicFlow->mapTo(this, point)); } void ClassicComicsView::requestedItemContextMenu(const QPoint &point) { emit customContextMenuItemRequested(tableView->mapTo(this, point)); } void ClassicComicsView::requestedHeaderContextMenu(const QPoint &point) { QMenu menu; for (int i = 0; i < tableView->model()->columnCount(); ++i) { auto title = tableView->model()->headerData(i, Qt::Horizontal).toString(); if (!title.isEmpty()) { auto action = menu.addAction(tableView->model()->headerData(i, Qt::Horizontal).toString()); action->setCheckable(true); action->setChecked(!tableView->isColumnHidden(i)); connect(action, &QAction::toggled, tableView, [this, i](bool checked) { tableView->horizontalHeader()->setSectionHidden(i, !checked); }); connect(action, &QAction::toggled, this, &ClassicComicsView::saveTableHeadersStatus); } } menu.exec(this->tableView->horizontalHeader()->mapToGlobal(point)); } 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) { if (model == nullptr) { return; } 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::saveSplitterStatus() { settingsMutex.lock(); if (!searching) settings->setValue(COMICS_VIEW_FLOW_SPLITTER_STATUS, sVertical->saveState()); settingsMutex.unlock(); } void ClassicComicsView::applyModelChanges(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { Q_UNUSED(topLeft); Q_UNUSED(bottomRight); if (roles.contains(ComicModel::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::addItemsToFlow(const QModelIndex &parent, int from, int to) { Q_UNUSED(parent); for (int i = from; i <= to; i++) { auto coverPath = model->index(i, 0).data(ComicModel::CoverPathRole).toUrl().toLocalFile(); comicFlow->add(coverPath, i); } } void ClassicComicsView::closeEvent(QCloseEvent *event) { toolbar->removeAction(startSeparatorAction); toolbar->removeAction(hideFlowViewAction); saveTableHeadersStatus(); saveSplitterStatus(); ComicsView::closeEvent(event); } void ClassicComicsView::setupSearchingIcon() { searchingIcon = new QWidget(comicFlow); auto h = new QHBoxLayout; QPixmap p(":/images/searching_icon.png"); QLabel *l = new QLabel(searchingIcon); l->setPixmap(p); l->setFixedSize(p.size()); h->addWidget(l, 0, Qt::AlignCenter); searchingIcon->setLayout(h); searchingIcon->setStyleSheet(QString("QWidget {border : none; background-color: #000000;}")); hideSearchingIcon(); } void ClassicComicsView::showSearchingIcon() { stack->setCurrentWidget(searchingIcon); } void ClassicComicsView::hideSearchingIcon() { stack->setCurrentWidget(comicFlow); }