Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37734818
en ru br
Репозитории ALT

Группа :: Офис
Пакет: gsimplecal

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

pax_global_header00006660000000000000000000000064121341212230014501gustar00rootroot0000000000000052 comment=8a336e4e25bdb62fc0f5deb7893e240b71114e84
gsimplecal-0.8/000075500000000000000000000000001213412122300134665ustar00rootroot00000000000000gsimplecal-0.8/.empty000064400000000000000000000000001213412122300146130ustar00rootroot00000000000000gsimplecal-0.8/.gear/000075500000000000000000000000001213412122300144625ustar00rootroot00000000000000gsimplecal-0.8/.gear/rules000064400000000000000000000000631213412122300155360ustar00rootroot00000000000000tar: . name=@name@-@version@ base=@name@-@version@
gsimplecal-0.8/.gitignore000064400000000000000000000003101213412122300154500ustar00rootroot00000000000000*.o

aclocal.m4
autom4te.cache/
config.log
config.status
configure
depcomp
install-sh
missing
src/.deps/

Makefile
Makefile.in
doc/Makefile
doc/Makefile.in
src/Makefile
src/Makefile.in
src/gsimplecal
gsimplecal-0.8/AUTHORS000064400000000000000000000005321213412122300145360ustar00rootroot00000000000000Authors & Contributors:
* Dmitry Medvinsky <dmedvinsky@gmail.com>
* Kim Hempel <kim@hempel.nu>: issue reports, patches
* Victor Feight <vrfeight3@gmail.com>: Arch Linux package
* Joshua Saddler <nightmorph@gentoo.org>: Gentoo Linux package
* Filip Pytloun <filip.pytloun@stickfish.com>: Fedora Linux package
* maelnor: Gentoo Linux package
gsimplecal-0.8/ChangeLog000064400000000000000000000011321213412122300152350ustar00rootroot000000000000002011-04-03: v0.8:
- Fix segmentation fault in the clock
+ Add keyboard bindings to go to the current date

2011-03-26: v0.7:
+ Mark today even when selecting some other day

2010-10-18: v0.6:
+ Add next_month and prev_month command line arguments
+ Add more config options (see man page)

2010-07-13: v0.5:
+ Add keyboard shortcuts to close the gsimplecal
* Add program crashes handling
+ Add keyboard shortcuts to switch months and years

2010-05-29: v0.4:
+ Use semaphores instead of libunique

2010-03-27: v0.3:
+ Migrate to autotools

2010-03-22: v0.2:
+ World clocks

2009-07-04: v0.1:
+ Calendar
gsimplecal-0.8/LICENSE000064400000000000000000000027241213412122300145000ustar00rootroot00000000000000Copyright (c) 2009, Dmitry Medvinsky

Some rights reserved.

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.

* The names of the contributors may not 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.
gsimplecal-0.8/Makefile.am000064400000000000000000000000221213412122300155140ustar00rootroot00000000000000SUBDIRS = src doc
gsimplecal-0.8/NEWS000064400000000000000000000000001213412122300141530ustar00rootroot00000000000000gsimplecal-0.8/README000064400000000000000000000000551213412122300143460ustar00rootroot00000000000000gsimplecal - lightweight gui calendar applet
gsimplecal-0.8/README.rst000064400000000000000000000020721213412122300151560ustar00rootroot00000000000000============
Gsimplecal
============
Gsimplecal is a lightweight calendar applet written in C++ using GTK2.

It was intentionally made for use with tint2_ panel in the openbox_ environment
to be launched upon clock click, but of course it will work without it. In
fact, binding the gsimplecal to some hotkey in you window manager will probably
make you happy. The thing is that when it is started it first shows up, when
you run it again it closes the running instance. In that way it is very easy to
integrate anywhere. No need to write some wrapper scripts or whatever.

Also, you can configure it to not only show the calendar, but also display
multiple clocks for different world timezones. Read the manual page for the
details (there is info about keyboard controls as well!).

Feel free to ask me anything and do not hesitate to post an issue. I don't
get a lot of questions and I feel kind of lonely. ;)

.. _tint2: http://code.google.com/p/tint2/
.. _openbox: http://openbox.org/wiki/Main_Page

.. image:: https://github.com/dmedvinsky/gsimplecal/raw/gh-pages/g/scrot2.png
gsimplecal-0.8/autogen.sh000075500000000000000000000000421213412122300154630ustar00rootroot00000000000000#!/bin/sh

autoreconf -i -s -f -v
gsimplecal-0.8/autoreconf.sh000075500000000000000000000000471213412122300161730ustar00rootroot00000000000000#!/bin/sh
autoreconf --force --install
gsimplecal-0.8/configure.ac000064400000000000000000000027551213412122300157650ustar00rootroot00000000000000# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65])
AC_INIT([gsimplecal],
[0.8],
[http://github.com/dmedvinsky/gsimplecal/issues],
[gsimplecal],
[http://github.com/dmedvinsky/gsimplecal])

AM_INIT_AUTOMAKE([-Wall -Werror foreign])

AC_CONFIG_SRCDIR([src/gsimplecal.cpp])

# Checks for programs.
AC_LANG([C++])
AC_PROG_CXX
AC_PROG_INSTALL
PKG_PROG_PKG_CONFIG

# Checks for libraries.
PKG_CHECK_MODULES([GTK2], [gtk+-2.0])
AC_SUBST(GTK2_CFLAGS)
AC_SUBST(GTK2_LIBS)

# Checks for header files.
AC_CHECK_HEADERS([iostream \
string \
sstream \
fstream \
vector \
cstdlib \
stdlib.h \
sys/time.h \
sys/types.h \
sys/ipc.h \
sys/sem.h \
signal.h \
limits.h])

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CHECK_FUNCS([atexit \
gettimeofday \
setenv \
signal \
kill \
semget \
semctl \
ftok \
readlink])

#
AM_CPPFLAGS="-Wall"
AM_LDFLAGS="-Wl,--as-needed"
AC_SUBST(AM_CFLAGS)
AC_SUBST(AM_LDFLAGS)

AC_CONFIG_FILES([Makefile
doc/Makefile
src/Makefile])

AC_OUTPUT
gsimplecal-0.8/doc/000075500000000000000000000000001213412122300142335ustar00rootroot00000000000000gsimplecal-0.8/doc/Makefile.am000064400000000000000000000000721213412122300162660ustar00rootroot00000000000000man1_MANS = $(PACKAGE_NAME).1

EXTRA_DIST = $(man1_MANS)

gsimplecal-0.8/doc/gsimplecal.1000064400000000000000000000101411213412122300164320ustar00rootroot00000000000000.TH GSIMPLECAL 1 "2010-10-10"
.SH NAME
gsimplecal \- lightweight calendar applet


.SH SYNOPSIS
.B gsimplecal
.br
.B gsimplecal
next_month
.br
.B gsimplecal
prev_month


.SH DESCRIPTION
This manual page documents the usage of the
.B gsimplecal
command.

.PP
.B gsimplecal
is a lightweight calendar applet. When it is started, it first shows up, when
you run it again, it closes the running instance. It was intentionally made for
use with tint2 panel to be launched upon clock click, but of course it will
work without it, you can bind it to some hotkey in you window manager, for
example.

.PP
When you provide one of the arguments Б─■
.B next_month
or
.B prev_month
Б─■ instead of closing the running instance, the displaying month is changed.


.SH CONFIGURATION
.PP
You may configure gsimplecal to display different world timezones clocks.
To make it, you should create
.nh
\fB$XDG_CONFIG_HOME/gsimplecal/config\fP
.ny
file (usually it will be
.nh
~/.config/gsimplecal/config)
.ny
with the following contents:

.IP
show_calendar = 1
.br
show_timezones = 1
.br
mark_today = 1
.br
clock_format = %a %d %b %H:%M
.br
mainwindow_decorated = 0
.br
mainwindow_keep_above = 1
.br
mainwindow_sticky = 0
.br
mainwindow_skip_taskbar = 1
.br
mainwindow_position = none
.br
clock_label = UTC
.br
clock_tz = :UTC
.br
clock_label = Local
.br
clock_tz =

.PP
The options are pretty self explanatory, but here is detailed description:

.TP 5
\fBshow_calendar\fP: 1 or 0, defaults to 1.
Sets whether the calendar should be shown. Most users want this option to be 1.

.TP 5
\fBshow_timezones\fP: 1 or 0, defaults to 0.
Sets whether the different timezone clocks should be shown.

.TP 5
\fBmark_today\fP: 1 or 0, defaults to 1.
Sets whether today's date will be marked in the calendar (besides the default
selection, i.e. when you click on the other day, today will remain marked
somehow, e.g. in bold print).

.TP 5
\fBclock_format\fP: string
Sets the clocks format. Look \fIman strftime\fP for the possible formats.

.TP 5
\fBmainwindow_decorated\fP: 1 or 0, defaults to 0.
Tells your window manager to decorate or not to decorate the main window.

.TP 5
\fBmainwindow_keep_above\fP: 1 or 0, defaults to 1.
Sets whether the main window should be placed on top of other windows by your
window manager.

.TP 5
\fBmainwindow_sticky\fP: 1 or 0, defaults to 0.
Tells your window manager to show gsimplecal on all desktops.

.TP 5
\fBmainwindow_skip_taskbar\fP: 1 or 0, defaults to 1.
Sets whether the main window should be shown in the task list by your panel or
window manager.

.TP 5
\fBmainwindow_position\fP: mouse|center|none, defaults to mouse.
Tells your window manager where to place the gsimplecal window:
.TP 10
\fBmouse\fP
.br
close to the mouse cursor position (this one is useful when you bind gsimplecal
on some mouse click command);
.TP 10
\fBcenter\fP
.br
in the center of the screen;
.TP 10
\fBnone\fP
.br
it's up to your window manager to decide, where to place the window
(this one is useful when you bind gsimplecal invocation on some hotkey, so you
can configure your window manager to place gsimplecal in some predefined
position).

.TP 5
\fBclock_label\fP and \fBclock_tz\fP: string
These two options should go in pairs and \fBmust\fP be in the order given.
.br
Each pair creates new clock. The clock_label variable sets the string to be
displayed near the clock, the clock_tz sets the timezone.
.br
If you omit the value for clock_tz, local time will be shown.
.br
For a list of timezones see \fIman timezone\fP, or \fIls /usr/share/zoneinfo\fP


.SH KEYBOARD ACCELERATORS
.PP
You may use the following keyboard accelerators while gsimplecal window has a focus:

.IP
Escape, Ctrl+w, Ctrl+q: close the window
.br
j: switch to the next month
.br
k: switch to the previous month
.br
J: jump one year forward
.br
K: jump one year backward
.br
g, Home: jump to the current date

.PP
These are not yet configurable, but I'm working on it.


.SH REPORTING BUGS
.PP
Please, report any issues to the gsimplecal issue tracker, available at:
.nh
http://github.com/dmedvinsky/gsimplecal/issues
.ny


.SH AUTHOR
Created by Dmitry Medvinsky et al.


.SH SEE ALSO
tzset(3),
strftime(3)
gsimplecal-0.8/gsimplecal.spec000064400000000000000000000015141213412122300164630ustar00rootroot00000000000000Name: gsimplecal
Version: 0.8
Release: alt1.qa1

Summary: Simple and lightweight GTK calendar
License: BSD-Style
Group: Office
Url: https://github.com/dmedvinsky/gsimplecal/

Packager: Egor Glukhov <kaman@altlinux.org>
Source: %name-%version.tar

BuildRequires: gcc-c++ libgtk+2-devel

%description
%name is a lightweight calendar application written in C++ using GTK2.

It was intentionally made for use with tint2 panel in the openbox environment
to be launched upon clock click, but of course it will work without it.

%prep
%setup

%build
%autoreconf
%configure
%make_build

%install
%makeinstall_std

%files
%_bindir/%name
%_man1dir/*

%changelog
* Fri Apr 19 2013 Dmitry V. Levin (QA) <qa_ldv@altlinux.org> 0.8-alt1.qa1
- NMU: rebuilt for updated dependencies.

* Mon May 9 2011 Egor Glukhov <kaman@altlinux.org> 0.8-alt1
- Initial build
gsimplecal-0.8/src/000075500000000000000000000000001213412122300142555ustar00rootroot00000000000000gsimplecal-0.8/src/Boxable.cpp000064400000000000000000000002651213412122300163400ustar00rootroot00000000000000#include <gtk/gtk.h>

#include "Boxable.hpp"


void Boxable::addToBox(GtkWidget* box)
{
if (widget) {
gtk_box_pack_start(GTK_BOX(box), widget, false, false, 0);
}
}
gsimplecal-0.8/src/Boxable.hpp000064400000000000000000000003051213412122300163400ustar00rootroot00000000000000#ifndef BOXABLE_HPP
#define BOXABLE_HPP

#include <gtk/gtk.h>


class Boxable
{
public:
virtual void addToBox(GtkWidget* box);

protected:
Boxable() {};

GtkWidget* widget;

};

#endif
gsimplecal-0.8/src/Calendar.cpp000064400000000000000000000041651213412122300165000ustar00rootroot00000000000000#include <gtk/gtk.h>

#include "Calendar.hpp"
#include "Config.hpp"


void monthChangedCb(GtkCalendar *calendar, gpointer cls)
{
if (cls) {
((Calendar*)cls)->markToday();
}
}


Calendar::Calendar()
{
widget = gtk_calendar_new();
gtk_calendar_set_display_options(GTK_CALENDAR(widget),
(GtkCalendarDisplayOptions)(GTK_CALENDAR_SHOW_HEADING +
GTK_CALENDAR_SHOW_DAY_NAMES));

Config* config = Config::getInstance();
if (config->mark_today) {
// Store today date to know be able to mark it after month changes.
gtk_calendar_get_date((GtkCalendar*)widget,
&today_year, &today_month, &today_day);
markToday();
gtk_signal_connect(GTK_OBJECT(widget), "month-changed",
GTK_SIGNAL_FUNC(monthChangedCb), (gpointer)this);
}

gtk_widget_show(widget);
}

Calendar::~Calendar()
{
gtk_widget_destroy(widget);
}

void Calendar::nextYear()
{
_change(1, 0);
}
void Calendar::prevYear()
{
_change(-1, 0);
}

void Calendar::nextMonth()
{
_change(0, 1);
}
void Calendar::prevMonth()
{
_change(0, -1);
}

void Calendar::_change(int year_offset, int month_offset)
{
int year, month;
gtk_calendar_get_date((GtkCalendar*)widget, (guint*)&year, (guint*)&month, NULL);
month += month_offset;
if (month > 11) {
month = 0;
year_offset++;
} else if (month < 0) {
month = 11;
year_offset--;
}
year += year_offset;
gtk_calendar_select_month((GtkCalendar*)widget, (guint)month, (guint)year);
}

bool Calendar::markToday()
{
guint year, month;
gtk_calendar_get_date((GtkCalendar*)widget, &year, &month, NULL);
if (year == today_year && month == today_month) {
gtk_calendar_mark_day((GtkCalendar*)widget, today_day);
return true;
} else {
gtk_calendar_unmark_day((GtkCalendar*)widget, today_day);
return false;
}
}

void Calendar::goToday()
{
gtk_calendar_select_month((GtkCalendar*)widget, today_month, today_year);
gtk_calendar_select_day((GtkCalendar*)widget, today_day);
}
gsimplecal-0.8/src/Calendar.hpp000064400000000000000000000006771213412122300165110ustar00rootroot00000000000000#ifndef CALENDAR_HPP
#define CALENDAR_HPP

#include <gtk/gtk.h>

#include "Boxable.hpp"


class Calendar : public Boxable
{
public:
Calendar();
~Calendar();

void nextYear();
void prevYear();
void nextMonth();
void prevMonth();
void goToday();

bool markToday();

protected:
void _change(int year_offset, int month_offset);

private:
guint today_year;
guint today_month;
guint today_day;
};

#endif
gsimplecal-0.8/src/Clock.cpp000064400000000000000000000027641213412122300160250ustar00rootroot00000000000000#include <string>

#include <stdlib.h>
#include <sys/time.h>
#include <gtk/gtk.h>

#include "Clock.hpp"
#include "Config.hpp"

using namespace std;


Clock::Clock(const string& label, const string& timezone)
{
this->timezone = timezone;

widget = gtk_hbox_new(false, 0);

label_label = gtk_label_new(label.c_str());
time_label = gtk_label_new(timezone.c_str());

gtk_box_pack_start(GTK_BOX(widget), label_label, false, false, 10);
gtk_box_pack_end(GTK_BOX(widget), time_label, false, false, 10);

gtk_widget_show(label_label);
gtk_widget_show(time_label);
gtk_widget_show(widget);
}

Clock::~Clock()
{
gtk_widget_destroy(time_label);
gtk_widget_destroy(label_label);
gtk_widget_destroy(widget);
}


void Clock::updateTime(const timeval& time)
{
string time_text = getTimeForTZ(time, timezone);
gtk_label_set_text(GTK_LABEL(time_label), time_text.c_str());
}

string Clock::getTimeForTZ(const timeval& time, const string& zone)
{
struct tm* result;
if (zone.length()) {
const char* old_tz = getenv("TZ");
setenv("TZ", zone.c_str(), 1);

result = localtime(&time.tv_sec);

if (old_tz) {
setenv("TZ", old_tz, 1);
} else {
unsetenv("TZ");
}
} else {
result = localtime(&time.tv_sec);
}

// format time
Config* config = Config::getInstance();
char buffer[64];
strftime(buffer, sizeof(buffer), config->clock_format.c_str(), result);
return string(buffer);
}
gsimplecal-0.8/src/Clock.hpp000064400000000000000000000007221213412122300160220ustar00rootroot00000000000000#ifndef CLOCK_HPP
#define CLOCK_HPP

#include <string>
#include <sys/time.h>
#include <gtk/gtk.h>

#include "Boxable.hpp"

using namespace std;


class Clock : public Boxable
{
public:
Clock(const string& label, const string& timezone);
~Clock();

void updateTime(const timeval& time);

protected:
string timezone;

GtkWidget* label_label;
GtkWidget* time_label;

string getTimeForTZ(const timeval& time, const string& zone);

};

#endif
gsimplecal-0.8/src/Config.cpp000064400000000000000000000076271213412122300162020ustar00rootroot00000000000000#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

#include <glib/gstdio.h>
#include <gtk/gtk.h>

#include "Config.hpp"

using namespace std;


Config* Config::_instance = NULL;

Config* Config::getInstance()
{
if (_instance == NULL) {
_instance = new Config();
atexit(Destroy);
}
return _instance;
}

void Config::Destroy()
{
delete _instance;
_instance = NULL;
}


Config::Config()
{
getDefaults();
if (getFile()) {
readFile();
}
}

Config::~Config()
{
for (unsigned int i = 0; i < clocks.size(); i++) {
delete clocks[i];
}
}


void Config::getDefaults()
{
show_calendar = true;
show_timezones = false;
clock_format = string("%H:%M");
mainwindow_decorated = false;
mainwindow_keep_above = true;
mainwindow_sticky = false;
mainwindow_skip_taskbar = true;
mainwindow_position = GTK_WIN_POS_MOUSE;
mark_today = true;
}

bool Config::getFile()
{
// use XDG config dir (~/.config/ usually)
char *path_to_config;
path_to_config = g_build_filename(g_get_user_config_dir(),
"gsimplecal", "config", NULL);
if (g_file_test(path_to_config, G_FILE_TEST_EXISTS)) {
file.open(path_to_config, ios::in);
}
g_free(path_to_config);
return file.is_open();
}

void Config::readFile()
{
string line;
while (!file.eof()) {
getline(file, line);
parseLine(line);
}
file.close();
}

void Config::parseLine(string line)
{
if (!line.length() || line[0] == '#') {
return;
}
int pos;
for (pos = line.length() - 1; pos >= 0; pos--) {
if (line[pos] == '=') {
break;
}
}
if (pos == -1) {
return;
}
string var = strip(line.substr(0, pos));
string val = strip(line.substr(pos + 1));

addOption(var, val);
}

void Config::addOption(string var, string val)
{
if (var == "show_calendar") {
if (!fromString<bool>(show_calendar, val)) {
show_calendar = true;
}
} else if (var == "show_timezones") {
if (!fromString<bool>(show_timezones, val)) {
show_timezones = false;
}
} else if (var == "clock_format") {
clock_format = val;
} else if (var == "clock_label") {
ClockInfo* clockinfo = new ClockInfo;
clockinfo->label = val;
clocks.push_back(clockinfo);
} else if (var == "clock_tz") {
clocks[clocks.size() - 1]->timezone = val;
} else if (var == "mainwindow_decorated") {
if (!fromString<bool>(mainwindow_decorated, val)) {
mainwindow_decorated = false;
}
} else if (var == "mainwindow_keep_above") {
if (!fromString<bool>(mainwindow_keep_above, val)) {
mainwindow_keep_above = true;
}
} else if (var == "mainwindow_sticky") {
if (!fromString<bool>(mainwindow_sticky, val)) {
mainwindow_sticky = false;
}
} else if (var == "mainwindow_skip_taskbar") {
if (!fromString<bool>(mainwindow_skip_taskbar, val)) {
mainwindow_skip_taskbar = true;
}
} else if (var == "mainwindow_position") {
if (val == "center") {
mainwindow_position = GTK_WIN_POS_CENTER;
} else if (val == "mouse") {
mainwindow_position = GTK_WIN_POS_MOUSE;
} else {
mainwindow_position = GTK_WIN_POS_NONE;
}
} else if (var == "mark_today") {
if (!fromString<bool>(mark_today, val)) {
mark_today = true;
}
}
}

template <class T> bool Config::fromString(T& t, const string& s)
{
istringstream iss(s);
return !(iss >> t).fail();
}

string Config::strip(const string& s)
{
string::size_type const first = s.find_first_not_of(' ');
if (first == string::npos) {
return string();
}
return s.substr(first, s.find_last_not_of(' ') - first + 1);
}
gsimplecal-0.8/src/Config.hpp000064400000000000000000000017561213412122300162040ustar00rootroot00000000000000#ifndef CONFIG_HPP
#define CONFIG_HPP

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

#include <gtk/gtk.h>

using namespace std;

typedef struct _ClockInfo
{
string label;
string timezone;
} ClockInfo;

class Config
{
public:
static Config* getInstance();

// options
bool show_calendar;
bool show_timezones;
string clock_format;
vector<ClockInfo*> clocks;
bool mark_today;

bool mainwindow_decorated;
bool mainwindow_keep_above;
bool mainwindow_sticky;
bool mainwindow_skip_taskbar;
GtkWindowPosition mainwindow_position;

private:
static Config* _instance;
static void Destroy();

template <class T> bool fromString(T& t, const string& s);
string strip(string const& str);

std::ifstream file;

protected:
explicit Config();
~Config();

void getDefaults();
bool getFile();
void readFile();
void parseLine(string line);
void addOption(string var, string val);

};

#endif
gsimplecal-0.8/src/MainWindow.cpp000064400000000000000000000107641213412122300170450ustar00rootroot00000000000000#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include "MainWindow.hpp"
#include "Config.hpp"
#include "Calendar.hpp"
#include "Timezones.hpp"


bool closeCallback(GtkAccelGroup *group, GObject *obj, guint keyval,
GdkModifierType mod, gpointer user_data)
{
if (user_data) {
((MainWindow*)user_data)->close();
}
return true;
}
bool nextYearCallback(GtkAccelGroup *group, GObject *obj, guint keyval,
GdkModifierType mod, gpointer user_data)
{
if (user_data) {
((MainWindow*)user_data)->nextYear();
}
return true;
}
bool prevYearCallback(GtkAccelGroup *group, GObject *obj, guint keyval,
GdkModifierType mod, gpointer user_data)
{
if (user_data) {
((MainWindow*)user_data)->prevYear();
}
return true;
}
bool nextMonthCallback(GtkAccelGroup *group, GObject *obj, guint keyval,
GdkModifierType mod, gpointer user_data)
{
if (user_data) {
((MainWindow*)user_data)->nextMonth();
}
return true;
}
bool prevMonthCallback(GtkAccelGroup *group, GObject *obj, guint keyval,
GdkModifierType mod, gpointer user_data)
{
if (user_data) {
((MainWindow*)user_data)->prevMonth();
}
return true;
}
bool goTodayCallback(GtkAccelGroup *group, GObject *obj, guint keyval,
GdkModifierType mod, gpointer user_data)
{
if (user_data) {
((MainWindow*)user_data)->goToday();
}
return true;
}


MainWindow::MainWindow()
{
Config* config = Config::getInstance();

widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(widget), "gsimplecal");
gtk_window_set_decorated(GTK_WINDOW(widget),
config->mainwindow_decorated);
gtk_window_set_keep_above(GTK_WINDOW(widget),
config->mainwindow_keep_above);
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(widget),
config->mainwindow_skip_taskbar);
gtk_window_set_position(GTK_WINDOW(widget),
config->mainwindow_position);
if (config->mainwindow_sticky) {
gtk_window_stick(GTK_WINDOW(widget));
}

// Create box for child items
children_box = gtk_vbox_new(false, 10);

calendar = NULL;
if (config->show_calendar) {
calendar = new Calendar();
calendar->addToBox(children_box);
}
timezones = NULL;
if (config->show_timezones) {
timezones = new Timezones();
timezones->updateTime();
timezones->addToBox(children_box);
}

gtk_container_add(GTK_CONTAINER(widget), children_box);
gtk_widget_show(children_box);
gtk_widget_show(widget);

// Connect keyboard accelerators
GtkAccelGroup *accelerators = gtk_accel_group_new();
GClosure *closure;

Shortcut keys[] = {{GDK_Escape, 0, closeCallback},
{GDK_q, GDK_CONTROL_MASK, closeCallback},
{GDK_w, GDK_CONTROL_MASK, closeCallback},
{GDK_j, GDK_SHIFT_MASK, nextYearCallback},
{GDK_k, GDK_SHIFT_MASK, prevYearCallback},
{GDK_j, 0, nextMonthCallback},
{GDK_k, 0, prevMonthCallback},
{GDK_g, 0, goTodayCallback},
{GDK_Home, 0, goTodayCallback}};
for (int key = 0; key < 9; key++) {
closure = g_cclosure_new(G_CALLBACK(keys[key].func), (gpointer)this, NULL);
gtk_accel_group_connect(accelerators, keys[key].key,
(GdkModifierType)keys[key].modifier,
(GtkAccelFlags)NULL, closure);
g_closure_unref(closure);
}

gtk_window_add_accel_group(GTK_WINDOW(widget), accelerators);
}

MainWindow::~MainWindow()
{
if (calendar) {
delete calendar;
}
if (timezones) {
delete timezones;
}
gtk_widget_destroy(children_box);
gtk_widget_destroy(widget);
}

GtkWindow* MainWindow::getWindow()
{
return GTK_WINDOW(widget);
}

void MainWindow::updateTime()
{
if (timezones) {
timezones->updateTime();
}
}

void MainWindow::close()
{
gtk_signal_emit_by_name(GTK_OBJECT(widget), "destroy");
}

void MainWindow::goToday()
{
calendar->goToday();
}
void MainWindow::nextMonth()
{
calendar->nextMonth();
}
void MainWindow::prevMonth()
{
calendar->prevMonth();
}

void MainWindow::nextYear()
{
calendar->nextYear();
}
void MainWindow::prevYear()
{
calendar->prevYear();
}
gsimplecal-0.8/src/MainWindow.hpp000064400000000000000000000011511213412122300170400ustar00rootroot00000000000000#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <gtk/gtk.h>

#include "Calendar.hpp"
#include "Timezones.hpp"


class MainWindow
{
public:
MainWindow();
~MainWindow();

GtkWindow* getWindow();
void updateTime();

void close();

void nextMonth();
void prevMonth();
void nextYear();
void prevYear();
void goToday();

Calendar* calendar;

protected:
GtkWidget* widget;
GtkWidget* children_box;
Timezones* timezones;

};

struct Shortcut
{
int key;
int modifier;
bool (*func)(GtkAccelGroup*, GObject*, guint, GdkModifierType, void*);
};

#endif
gsimplecal-0.8/src/Makefile.am000064400000000000000000000005071213412122300163130ustar00rootroot00000000000000AM_CPPFLAGS = @GTK2_CFLAGS@
LIBS = @GTK2_LIBS@

bin_PROGRAMS = gsimplecal
gsimplecal_SOURCES = \
Boxable.cpp \
Boxable.hpp \
Calendar.cpp \
Calendar.hpp \
Clock.cpp \
Clock.hpp \
Config.cpp \
Config.hpp \
gsimplecal.cpp \
MainWindow.cpp \
MainWindow.hpp \
Timezones.cpp \
Timezones.hpp \
Unique.cpp \
Unique.hpp
gsimplecal-0.8/src/Timezones.cpp000064400000000000000000000017051213412122300167410ustar00rootroot00000000000000#include <sys/time.h>
#include <gtk/gtk.h>

#include "Config.hpp"
#include "Timezones.hpp"
#include "Clock.hpp"


Timezones::Timezones()
{
widget = gtk_vbox_new(false, 0);

Config* config = Config::getInstance();
for (unsigned int clock_num = 0; clock_num < config->clocks.size(); clock_num++) {
Clock* clock = new Clock(config->clocks[clock_num]->label,
config->clocks[clock_num]->timezone);
clock->addToBox(widget);
clocks.push_back(clock);
}

gtk_widget_show(widget);
}

Timezones::~Timezones()
{
for (unsigned int clock_num = 0; clock_num < clocks.size(); clock_num++) {
delete clocks[clock_num];
}
gtk_widget_destroy(widget);
}

void Timezones::updateTime()
{
struct timeval clock_time;
gettimeofday(&clock_time, 0);
for (unsigned int clock_num = 0; clock_num < clocks.size(); clock_num++) {
clocks[clock_num]->updateTime(clock_time);
}
}
gsimplecal-0.8/src/Timezones.hpp000064400000000000000000000004351213412122300167450ustar00rootroot00000000000000#ifndef TIMEZONES_HPP
#define TIMEZONES_HPP

#include <vector>

#include <gtk/gtk.h>

#include "Boxable.hpp"
#include "Clock.hpp"


class Timezones : public Boxable
{
public:
Timezones();
~Timezones();

void updateTime();

protected:
vector<Clock*> clocks;

};

#endif
gsimplecal-0.8/src/Unique.cpp000064400000000000000000000047031213412122300162330ustar00rootroot00000000000000#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <limits.h>
#include <sys/sem.h>
#include <signal.h>

#include "Unique.hpp"


union semun
{
int val;
};


Unique::Unique()
{
// Get path to the current binary.
// It's a bit ugly, I guess, to rely on /proc, but it'll do for now.
char szTmp[32];
sprintf(szTmp, "/proc/%d/exe", getpid());

char* filename = new char[PATH_MAX + 1];
int bytes = readlink(szTmp, filename,
sizeof(*filename) * PATH_MAX);
if (bytes > PATH_MAX - 1) {
bytes = PATH_MAX;
}
filename[bytes] = '\0';

// Get unique key for semaphore.
semaphore_key = ftok(filename, 1);
if (semaphore_key == -1) {
throw new UniqueException("ftok failed");
}
delete[] filename;
}

Unique::~Unique()
{
}

bool Unique::isRunning()
{
int semid = semget(semaphore_key, 0, 0);
if (semid == -1) {
return false;
}
return true;
}

void Unique::start()
{
if (!isRunning()) {
// Create semaphore; fail if already exists.
int semid = semget(semaphore_key, 1,
IPC_CREAT | IPC_EXCL | 0660);
if (semid == -1) {
throw UniqueException("semget failed while creating semaphore");
}

// Set initial semaphore value to the current pid, so we could use it to
// kill the process from the second instance.
union semun semopts;
semopts.val = getpid();
if (semctl(semid, 0, SETVAL, semopts) == -1) {
throw UniqueException("semctl (SETVAL) failed");
}
}
}

void Unique::signal(int signal_id)
{
kill(signal_id);
}
void Unique::kill()
{
kill(SIGTERM);
}
void Unique::kill(int signal_id)
{
if (isRunning()) {
// Get semaphore; fail if not present.
int semid = semget(semaphore_key, 1, 0660);
if (semid == -1) {
throw UniqueException("semget failed while trying to kill");
}

// Get the pid from semaphore value (stored before) to kill the process.
int pid = semctl(semid, 0, GETVAL, 0);
if (pid <= 0) {
throw UniqueException("semctl (GETVAL) failed");
}
if (::kill(pid, signal_id)) {
throw UniqueException("kill failed");
}
}
}

void Unique::stop()
{
int semid = semget(semaphore_key, 1, 0660);
if (semid != -1) {
semctl(semid, 0, IPC_RMID, 0);
}
}
gsimplecal-0.8/src/Unique.hpp000064400000000000000000000011331213412122300162320ustar00rootroot00000000000000#ifndef UNIQUE_HPP
#define UNIQUE_HPP

#include <exception>
#include <string>

#include <sys/types.h>


using namespace std;


class UniqueException : public exception
{
public:
UniqueException(string m="Unique Exception") : msg(m) {}
~UniqueException() throw() {}
const char* what() const throw() { return msg.c_str(); }

private:
string msg;
};


class Unique
{
public:
Unique();
~Unique();

bool isRunning();
void kill();
void kill(int signal_id);
void signal(int signal_id);
void start();
void stop();

protected:
key_t semaphore_key;

};

#endif
gsimplecal-0.8/src/gsimplecal.cpp000064400000000000000000000034771213412122300171140ustar00rootroot00000000000000#include <iostream>
#include <string.h>

#include <signal.h>
#include <gtk/gtk.h>

#include "MainWindow.hpp"
#include "Config.hpp"
#include "Unique.hpp"


MainWindow* main_window;


static void signal_handler(int signal_id)
{
if (signal_id == SIGTERM) {
gtk_main_quit();
} else if (signal_id == SIGUSR1) {
main_window->nextMonth();
} else if (signal_id == SIGUSR2) {
main_window->prevMonth();
}
}

static void destroy()
{
delete main_window;
gtk_main_quit();
}

static bool time_handler(GtkWidget *widget)
{
main_window->updateTime();
return true;
}

int main(int argc, char *argv[])
{
Unique* unique = new Unique();
if (unique->isRunning()) {
try {
if (argc >= 2 && strcmp(argv[1], "next_month") == 0) {
unique->signal(SIGUSR1);
} else if (argc >= 2 && strcmp(argv[1], "prev_month") == 0) {
unique->signal(SIGUSR2);
} else {
unique->kill();
unique->stop();
}
return 0;
} catch (UniqueException e) {
std::cerr << "Looks like gsimplecal crashed last time."
<< " Exception message is: " << e.what() << ". Cleaning up."
<< std::endl;
unique->stop();
}
}

unique->start();
signal(SIGTERM, &signal_handler);
signal(SIGUSR1, &signal_handler);
signal(SIGUSR2, &signal_handler);

gtk_init(&argc, &argv);
main_window = new MainWindow();

gtk_signal_connect(GTK_OBJECT(main_window->getWindow()), "destroy",
GTK_SIGNAL_FUNC(destroy), NULL);

Config* config = Config::getInstance();
if (config->show_timezones) {
g_timeout_add(30000, (GSourceFunc)time_handler, NULL);
}

gtk_main();

unique->stop();
return 0;
}
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin