Files
wxWidgets/src/gtk/calctrl.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

253 lines
7.5 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: src/gtk/calctrl.cpp
// Purpose: implementation of the wxGtkCalendarCtrl
// Author: Marcin Wojdyr
// Copyright: (c) 2008 Marcin Wojdyr
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_CALENDARCTRL
#ifndef WX_PRECOMP
#endif //WX_PRECOMP
#include "wx/calctrl.h"
#include <gtk/gtk.h>
extern "C" {
static void gtk_day_selected_callback(GtkWidget *WXUNUSED(widget),
wxGtkCalendarCtrl *cal)
{
cal->GTKGenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
}
static void gtk_day_selected_double_click_callback(GtkWidget *WXUNUSED(widget),
wxGtkCalendarCtrl *cal)
{
cal->GTKGenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
}
static void gtk_month_changed_callback(GtkWidget *WXUNUSED(widget),
wxGtkCalendarCtrl *cal)
{
cal->GTKGenerateEvent(wxEVT_CALENDAR_PAGE_CHANGED);
}
// callbacks that send deprecated events
static void gtk_prev_month_callback(GtkWidget *WXUNUSED(widget),
wxGtkCalendarCtrl *cal)
{
cal->GTKGenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
}
static void gtk_prev_year_callback(GtkWidget *WXUNUSED(widget),
wxGtkCalendarCtrl *cal)
{
cal->GTKGenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
}
}
// ----------------------------------------------------------------------------
// wxGtkCalendarCtrl
// ----------------------------------------------------------------------------
bool wxGtkCalendarCtrl::Create(wxWindow *parent,
wxWindowID id,
const wxDateTime& date,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
{
if (!PreCreation(parent, pos, size) ||
!CreateBase(parent, id, pos, size, style, wxDefaultValidator, name))
{
wxFAIL_MSG(wxT("wxGtkCalendarCtrl creation failed"));
return false;
}
m_widget = gtk_calendar_new();
g_object_ref(m_widget);
SetDate(date.IsValid() ? date : wxDateTime::Today());
if (style & wxCAL_NO_MONTH_CHANGE)
g_object_set (G_OBJECT (m_widget), "no-month-change", true, NULL);
if (style & wxCAL_SHOW_WEEK_NUMBERS)
g_object_set (G_OBJECT (m_widget), "show-week-numbers", true, NULL);
g_signal_connect_after(m_widget, "day-selected",
G_CALLBACK (gtk_day_selected_callback),
this);
g_signal_connect_after(m_widget, "day-selected-double-click",
G_CALLBACK (gtk_day_selected_double_click_callback),
this);
g_signal_connect_after(m_widget, "month-changed",
G_CALLBACK (gtk_month_changed_callback),
this);
// connect callbacks that send deprecated events
g_signal_connect_after(m_widget, "prev-month",
G_CALLBACK (gtk_prev_month_callback),
this);
g_signal_connect_after(m_widget, "next-month",
G_CALLBACK (gtk_prev_month_callback),
this);
g_signal_connect_after(m_widget, "prev-year",
G_CALLBACK (gtk_prev_year_callback),
this);
g_signal_connect_after(m_widget, "next-year",
G_CALLBACK (gtk_prev_year_callback),
this);
m_parent->DoAddChild(this);
PostCreation(size);
return true;
}
void wxGtkCalendarCtrl::GTKGenerateEvent(wxEventType type)
{
// First check if the new date is in the specified range.
wxDateTime dt = GetDate();
if ( !IsInValidRange(dt) )
{
if ( m_validStart.IsValid() && dt < m_validStart )
dt = m_validStart;
else
dt = m_validEnd;
SetDate(dt);
return;
}
if ( type == wxEVT_CALENDAR_SEL_CHANGED )
{
// Don't generate this event if the new date is the same as the old
// one.
if ( m_selectedDate == dt )
return;
m_selectedDate = dt;
GenerateEvent(type);
// Also send the deprecated event together with the new one.
GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
}
else
{
GenerateEvent(type);
}
}
bool wxGtkCalendarCtrl::IsInValidRange(const wxDateTime& dt) const
{
return (!m_validStart.IsValid() || m_validStart <= dt) &&
(!m_validEnd.IsValid() || dt <= m_validEnd);
}
bool
wxGtkCalendarCtrl::SetDateRange(const wxDateTime& lowerdate,
const wxDateTime& upperdate)
{
if ( lowerdate.IsValid() && upperdate.IsValid() && lowerdate >= upperdate )
return false;
m_validStart = lowerdate;
m_validEnd = upperdate;
return true;
}
bool
wxGtkCalendarCtrl::GetDateRange(wxDateTime *lowerdate,
wxDateTime *upperdate) const
{
if ( lowerdate )
*lowerdate = m_validStart;
if ( upperdate )
*upperdate = m_validEnd;
return m_validStart.IsValid() || m_validEnd.IsValid();
}
bool wxGtkCalendarCtrl::EnableMonthChange(bool enable)
{
if ( !wxCalendarCtrlBase::EnableMonthChange(enable) )
return false;
g_object_set (G_OBJECT (m_widget), "no-month-change", !enable, NULL);
return true;
}
bool wxGtkCalendarCtrl::SetDate(const wxDateTime& date)
{
if ( date.IsValid() && !IsInValidRange(date) )
return false;
g_signal_handlers_block_by_func(m_widget,
(gpointer) gtk_day_selected_callback, this);
g_signal_handlers_block_by_func(m_widget,
(gpointer) gtk_month_changed_callback, this);
m_selectedDate = date;
int year = date.GetYear();
int month = date.GetMonth();
int day = date.GetDay();
gtk_calendar_select_month(GTK_CALENDAR(m_widget), month, year);
gtk_calendar_select_day(GTK_CALENDAR(m_widget), day);
g_signal_handlers_unblock_by_func( m_widget,
(gpointer) gtk_month_changed_callback, this);
g_signal_handlers_unblock_by_func( m_widget,
(gpointer) gtk_day_selected_callback, this);
return true;
}
wxDateTime wxGtkCalendarCtrl::GetDate() const
{
guint year, monthGTK, day;
gtk_calendar_get_date(GTK_CALENDAR(m_widget), &year, &monthGTK, &day);
// GTK may return an invalid date, this happens at least when switching the
// month (or the year in case of February in a leap year) and the new month
// has fewer days than the currently selected one making the currently
// selected day invalid, e.g. just choosing May 31 and going back a month
// results in the date being (non existent) April 31 when we're called from
// gtk_prev_month_callback(). We need to manually work around this to avoid
// asserts from wxDateTime ctor.
const wxDateTime::Month month = static_cast<wxDateTime::Month>(monthGTK);
const guint dayMax = wxDateTime::GetNumberOfDays(month, year);
if ( day > dayMax )
day = dayMax;
return wxDateTime(day, month, year);
}
void wxGtkCalendarCtrl::Mark(size_t day, bool mark)
{
if (mark)
gtk_calendar_mark_day(GTK_CALENDAR(m_widget), day);
else
gtk_calendar_unmark_day(GTK_CALENDAR(m_widget), day);
}
#endif // wxUSE_CALENDARCTRL