first commit

This commit is contained in:
2026-02-21 17:11:31 +09:00
commit 18b4338361
4001 changed files with 365464 additions and 0 deletions

View File

@@ -0,0 +1,401 @@
#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)