402 lines
13 KiB
C++
402 lines
13 KiB
C++
|
|
#include "fm_calendar.h"
|
|
#if (USE_DATE_TIME_LIST)
|
|
#include <QDate>
|
|
#include <QPainter>
|
|
#include <QDebug>
|
|
#include <QMouseEvent>
|
|
#include <QVBoxLayout>
|
|
#include <QHBoxLayout>
|
|
#include "rm_include.h"
|
|
#include "../ui/fm_button.h"
|
|
#include "../data/rm_video_list.h"
|
|
#include "../data/rm_video_item_2ch.h"
|
|
#include "fm_colors.h"
|
|
#include "../core/rm_player.h"
|
|
|
|
FMCalendarFrame::FMCalendarFrame(QWidget *parent)
|
|
: QWidget(parent)
|
|
{
|
|
bLoadStarted = true;
|
|
setFixedHeight(250);
|
|
mLayout = new QVBoxLayout(this);
|
|
ZERO_LAYOUT(mLayout);
|
|
|
|
QWidget* toolbar = new QWidget(this);
|
|
toolbar->setFixedHeight(30);
|
|
mLayout->addWidget(toolbar);
|
|
QHBoxLayout* toolLayout = new QHBoxLayout(toolbar);
|
|
ZERO_LAYOUT(toolLayout);
|
|
|
|
before = FMButton::btnTypeTextColor(toolbar,toolLayout," < ","",QSize(20,20),g_default_text_button_color_set);
|
|
connect(before,SIGNAL(clicked()),SLOT(onChangeMonth()));
|
|
|
|
mYearLabel = new QLabel(toolbar);
|
|
mYearLabel->setAlignment(Qt::AlignCenter);
|
|
mYearLabel->setStyleSheet("font-family: Fixedsys;color : #DDDDDD;");
|
|
|
|
toolLayout->addWidget(mYearLabel);
|
|
|
|
next = FMButton::btnTypeTextColor(toolbar,toolLayout," > ","",QSize(20,20),g_default_text_button_color_set);
|
|
connect(next,SIGNAL(clicked()),SLOT(onChangeMonth()));
|
|
|
|
|
|
mCalendar = new FMCalendar(this);
|
|
mLayout->addWidget(mCalendar);
|
|
|
|
RMVideoFileList* fileList = RMVideoFileList::instance();
|
|
//connect(fileList,SIGNAL(listUpdateEnd(bool,RMVideoItem*)),this,SLOT(onListUpdateEnd(bool,RMVideoItem*)));
|
|
connect(fileList,SIGNAL(listUpdateStarted(bool)),this,SLOT(onListUpdateStarted(bool)));
|
|
|
|
|
|
refreshMonth();
|
|
|
|
//connect(fileList,SIGNAL(playItemFound(RMVideoItem*,int)),SLOT(onPlayItemFound(RMVideoItem*,int)));
|
|
//connect(fileList,SIGNAL(playNoMoreItem()),SLOT(onPlayNoMoreItem()));
|
|
|
|
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
|
|
|
|
}
|
|
void FMCalendarFrame::onPlayEvent(PLAY_EVENT event,RMVideoItem* item)
|
|
{
|
|
// PLAY_WILL_LOADED
|
|
if(event == PLAY_ITEM_SELECTED && item != NULL) {
|
|
playTime = item->startTime();
|
|
QDate pdate = item->startTime().date();
|
|
// 리스트 또는 다음파일 이동에서 재생되었는지
|
|
// '분' 항목에서 재생되었는지 확인 필요
|
|
|
|
QDate cdate = QDate(mCalendar->date.year(),mCalendar->date.month(),mCalendar->mSelectedDay);
|
|
|
|
if(cdate != pdate || bLoadStarted) {
|
|
|
|
// 년/월이 변경되었을 경우 달력을 다시 로딩
|
|
// 2023/06/30 -> 2023/07/01 로 변경시 적용안됨?
|
|
if(bLoadStarted || mCalendar->date.year() != pdate.year() || mCalendar->date.month() != pdate.month())
|
|
{
|
|
mCalendar->date.setDate(pdate.year(),pdate.month(),pdate.day());
|
|
mCalendar->mSelectedDay = pdate.day();
|
|
onChangeMonth(); // 달력 업데이트
|
|
}
|
|
|
|
mCalendar->date.setDate(pdate.year(),pdate.month(),pdate.day());
|
|
mCalendar->mSelectedDay = pdate.day();
|
|
mCalendar->update(); // 다시 그리기
|
|
|
|
mCalendar->updateDayItems(); // 날짜리스트 다시 로딩
|
|
// 리스트에서 전달되었으므로 리스트 없데이트 X
|
|
emit mCalendar->dateSelected(&mCalendar->mDayItems,&playTime,false);
|
|
//qInfo() << "DATE CHANGED:" << mCalendar->date << pdate << __FUNCTION__;
|
|
} else {
|
|
// 시간만 변경된 경우
|
|
//qInfo() << playTime << __FUNCTION__;
|
|
// 리스트에서 전달되었으므로 리스트 없데이트 X
|
|
emit mCalendar->playTime(&playTime,false);
|
|
}
|
|
|
|
if(bLoadStarted) {
|
|
bLoadStarted = false;
|
|
}
|
|
|
|
|
|
} else if (event == PLAY_DID_CLEARED) {
|
|
/*
|
|
mCalendar->mSelectedDay = -1;
|
|
mCalendar->update();
|
|
*/
|
|
}
|
|
}
|
|
|
|
void FMCalendarFrame::onListUpdateStarted(bool bLoading)
|
|
{
|
|
// 2회 발생하는 경우도 있으며 bLoading false 로 ..
|
|
if(bLoading) {
|
|
bLoadStarted = true;
|
|
}
|
|
//qInfo() << bLoadStarted << __FUNCTION__;
|
|
}
|
|
/*
|
|
// 파일 선택되면서 자동으로 처리되어 필요없음 ... ->
|
|
// 현재 표시되는 '월'일 경우 파일이 선택되더라도 자동으로 업데이트가 안되니
|
|
// 강제 업데이트가 필요함 onPlayEvent 의 PLAY_ITEM_SELECTED 는
|
|
// onListUpdateEnd 이전에 발생함
|
|
void FMCalendarFrame::onListUpdateEnd(bool bLoading, RMVideoItem* selected)
|
|
{
|
|
Q_UNUSED(bLoading)
|
|
Q_UNUSED(selected)
|
|
if(bLoading) {
|
|
qInfo() << selected << __FUNCTION__;
|
|
}
|
|
}
|
|
*/
|
|
|
|
void FMCalendarFrame::onChangeMonth()
|
|
{
|
|
FMButton* btn = qobject_cast<FMButton*>(sender());
|
|
if(btn == next) {
|
|
mCalendar->date = mCalendar->date.addMonths(1);
|
|
} else if (btn == before) {
|
|
mCalendar->date = mCalendar->date.addMonths(-1);
|
|
}
|
|
RMVideoFileList::instance()->getMonthList(mCalendar->date.year(),mCalendar->date.month(),mCalendar->mExists,mCalendar->mMonthItems);
|
|
|
|
// 월의 첫날짜로 구분
|
|
if(mCalendar->mMonthItems.isEmpty()) { // 없을경우...
|
|
mCalendar->mSelectedDay = -1;
|
|
} else {
|
|
mCalendar->mSelectedDay = mCalendar->mMonthItems.first()->startTime().date().day();
|
|
}
|
|
|
|
// 월 텍스트 변경
|
|
refreshMonth();
|
|
|
|
|
|
// 재생시 리스트 변경의 경우
|
|
if(btn == NULL) {
|
|
return;
|
|
}
|
|
|
|
mCalendar->updateDayItems();
|
|
mCalendar->update();
|
|
|
|
// 선택된 달에 영상이 존재할 경우
|
|
if(!mCalendar->mMonthItems.isEmpty()) {
|
|
static QDateTime tt;
|
|
tt = mCalendar->mDayItems.first()->startTime();
|
|
|
|
// 달력업데이트로 처리 하였으니 리스트 업데이트 = true
|
|
emit mCalendar->dateSelected(&mCalendar->mDayItems,&tt,true);
|
|
} else {
|
|
emit mCalendar->clearDate(); // 해당월에 날짜 없음
|
|
}
|
|
|
|
}
|
|
void FMCalendarFrame::refreshMonth()
|
|
{
|
|
mYearLabel->setText(QString::number(mCalendar->date.year()) + FM_WSTR(L"年 / ") + QString::number(mCalendar->date.month()) + FM_WSTR(L"月"));
|
|
}
|
|
|
|
|
|
FMCalendar::FMCalendar(QWidget *parent)
|
|
: QWidget(parent)
|
|
{
|
|
date = QDateTime::currentDateTime().date();// .setDate(2023,11,1);
|
|
mPressed = false;
|
|
mHoverDay = -1;
|
|
mSelectedDay = -1;
|
|
// 이벤트 등록해야 포커스 아닌 상태에서도 동작 가능
|
|
QCoreApplication::instance()->installEventFilter(this);
|
|
}
|
|
/*
|
|
void FMCalendar::selectDay(int day)
|
|
{
|
|
if(mExists.contains(day)) {
|
|
mSelectedDay = day;
|
|
updateDayItems();
|
|
qInfo() << __FUNCTION__;
|
|
emit dateSelected(&mDayItems,NULL);
|
|
}
|
|
}
|
|
*/
|
|
void FMCalendar::reset()
|
|
{
|
|
mPressed = false;
|
|
mHoverDay = -1;
|
|
mSelectedDay = -1;
|
|
mMonthItems.clear();
|
|
mDayItems.clear();
|
|
mExists.clear();
|
|
}
|
|
int FMCalendar::getDay(QPoint xy)
|
|
{
|
|
QDate d = QDate(date.year(),date.month(),1);
|
|
|
|
// 월별 일수
|
|
int days = d.daysInMonth();
|
|
|
|
// 요일 일=0,월=1, 화=2, 수=3
|
|
int dayOfWeek = d.dayOfWeek() % 7;
|
|
|
|
const int colCount = 7;
|
|
|
|
int rowCount = ceil(((double)(days + dayOfWeek) / (double)colCount)) + 1; // week of days
|
|
//int rowCount = ceil(((double)(days + dw) / (double)colCount)) + 1; // week of days
|
|
|
|
//QRect r = rect();
|
|
|
|
const int cw = size().width() / colCount;
|
|
const int rh = size().height() / rowCount;
|
|
|
|
int currentDay = 1;
|
|
for(int r=1;r<rowCount;r++) {
|
|
for(int c=0;c<colCount;c++) {
|
|
// 매월 1일의 시작 요일이 현재 요일보다 작을 경우(=이전달) 또는 다음달일 경우
|
|
if((r==1 && c < dayOfWeek) || currentDay > days) {
|
|
//qInfo() << "c < dayOfWeek:" << (c < dayOfWeek) << "c:" << c << "dayOfWeek:" << dayOfWeek << __FUNCTION__;
|
|
continue;
|
|
}
|
|
// int left, int top, int width, int height
|
|
QRect cr = QRect(c*cw,r*rh,cw,rh);
|
|
if(cr.contains(xy)) {
|
|
return currentDay;
|
|
}
|
|
|
|
currentDay++;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
bool FMCalendar::eventFilter(QObject *watched, QEvent *event)
|
|
{
|
|
if (watched == this && event->type() == QEvent::MouseMove && !mPressed)
|
|
{
|
|
QMouseEvent* me = static_cast<QMouseEvent *>(event);
|
|
// 날짜가 변경된 경우에만 업데이트
|
|
int d = getDay(me->pos());
|
|
if(d != mHoverDay) {
|
|
mHoverDay = d;
|
|
update();
|
|
}
|
|
return false;
|
|
}
|
|
return QWidget::eventFilter(watched, event);
|
|
}
|
|
|
|
void FMCalendar::mousePressEvent(QMouseEvent* event)
|
|
{
|
|
Q_UNUSED(event)
|
|
if(mExists.contains(mHoverDay) && event->button() == Qt::LeftButton) {
|
|
mPressed = true;
|
|
update();
|
|
}
|
|
}
|
|
void FMCalendar::updateDayItems()
|
|
{
|
|
mDayItems.clear();
|
|
for(int i=0;i<mMonthItems.size();i++) {
|
|
QDate d = mMonthItems.at(i)->startTime().date();
|
|
if(d.day() == mSelectedDay) {
|
|
mDayItems.append(mMonthItems.at(i));
|
|
}
|
|
}
|
|
}
|
|
void FMCalendar::mouseReleaseEvent(QMouseEvent* event)
|
|
{
|
|
Q_UNUSED(event)
|
|
if(mPressed && event->button() == Qt::LeftButton) {
|
|
mPressed = false;
|
|
if(mHoverDay > 0) {
|
|
|
|
mSelectedDay = mHoverDay;
|
|
updateDayItems();
|
|
static QDateTime tt = mDayItems.first()->startTime();
|
|
// 달력에서 업데이트 되었으니 리스트 업데이트
|
|
emit dateSelected(&mDayItems,&tt,true);
|
|
|
|
// 선택된 날짜의 파일로 이동
|
|
// X
|
|
// if(!mDayItems.isEmpty()) {
|
|
// emit listMove(mDayItems.first());
|
|
// }
|
|
}
|
|
|
|
update();
|
|
}
|
|
}
|
|
void FMCalendar::paintEvent(QPaintEvent *e)
|
|
{
|
|
QWidget::paintEvent(e);
|
|
|
|
//QDate d = QDate(mYear,mMonth,1);
|
|
|
|
// 월별 일수 (지정된 날짜의 1일로 확인)
|
|
QDate d = QDate(date.year(),date.month(),1);
|
|
int days = d.daysInMonth();
|
|
|
|
// 요일 일=0,월=1, 화=2, 수=3, 일=7??
|
|
int dw = d.dayOfWeek() % 7;
|
|
|
|
QPainter painter(this);
|
|
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
|
|
const int colCount = 7;
|
|
// 1일의 시작요일을 더해서 ROW 계산 필요
|
|
int rowCount = ceil(((double)(days + dw) / (double)colCount)) + 1; // week of days
|
|
|
|
//qInfo() << days << colCount << "rowCount" << rowCount << __FUNCTION__;
|
|
|
|
QRect r = this->rect();
|
|
r.adjust(0,0,-1,-1);
|
|
painter.fillRect(r,QColor(0x33,0x33,0x33));
|
|
|
|
int cw = size().width() / colCount;
|
|
int rh = size().height() / rowCount;
|
|
|
|
QString wd = FM_WSTR(L"日月火水木金土");
|
|
|
|
// 일~토 레이블 출력
|
|
painter.setPen(QPen(QColor(0xFF,0xFF,0xFF),1, Qt::SolidLine));
|
|
for(int c=0;c<colCount;c++) {
|
|
QRect cr = QRect(c*cw,0,cw,rh);
|
|
//painter.drawRect(cr);
|
|
painter.drawText(cr,wd.at(c),QTextOption(Qt::AlignCenter));
|
|
wd.at(c);
|
|
}
|
|
|
|
QFont font = QFont("Fixedsys");
|
|
font.setPixelSize(12);
|
|
painter.setFont(font);
|
|
|
|
int currentDay = 1;
|
|
for(int r=1;r<rowCount;r++) {
|
|
for(int c=0;c<colCount;c++) {
|
|
|
|
// DAY OF WEEK 2023/12/31 일 DW:7(일)
|
|
if((r==1 && c < dw) || currentDay > days) {
|
|
//qInfo() << "SKIP r:" << r << "rowCount:" << rowCount << "dw:" << dw << "c:" << c << __FUNCTION__;
|
|
continue;
|
|
}
|
|
|
|
// int left, int top, int width, int height
|
|
QRect cr = QRect(c*cw,r*rh,cw,rh);
|
|
cr.adjust(1,1,-1,-1);
|
|
|
|
// 영상이 존재하는 날자일 경우
|
|
if(mExists.contains(currentDay))
|
|
{
|
|
painter.fillRect(cr,QColor(FM_SILDER_COLOR));
|
|
if (currentDay == mSelectedDay) {
|
|
QRect cc = cr;
|
|
cc.adjust(4,4,-4,-4);
|
|
QPen p = QPen(QColor(FM_SELECTED_COLOR),5, Qt::SolidLine);
|
|
p.setJoinStyle(Qt::MiterJoin);
|
|
painter.setPen(p);
|
|
painter.drawRect(cc);
|
|
}
|
|
else if(currentDay == mHoverDay) {
|
|
QRect cc = cr;
|
|
cc.adjust(4,4,-4,-4);
|
|
QPen p = QPen(QColor(FM_HOVER_COLOR),5, Qt::SolidLine);
|
|
p.setJoinStyle(Qt::MiterJoin);
|
|
painter.setPen(p);
|
|
painter.drawRect(cc);
|
|
}
|
|
}
|
|
painter.setPen(QPen(QColor(0x44,0x44,0x44),1, Qt::SolidLine));
|
|
// setJoinStyle(Qt::MiterJoin);
|
|
painter.drawRect(cr);
|
|
|
|
// 일요일은 붉은색
|
|
painter.setPen(QPen(c == 0 ? QColor(0xDD,0x00,0x00) : QColor(0xDD,0xDD,0xDD),1, Qt::SolidLine));
|
|
|
|
painter.drawText(cr,QString::number(currentDay),QTextOption(Qt::AlignCenter));
|
|
currentDay++;
|
|
}
|
|
}
|
|
|
|
painter.setPen(QPen(QColor(0x88,0x88,0x88),1, Qt::SolidLine));
|
|
painter.drawRect(r);
|
|
}
|
|
#endif // #if (USE_DATE_TIME_LIST)
|