00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ClockTool.hh"
00026
00027 #include "ToolTheme.hh"
00028 #include "Screen.hh"
00029 #include "CommandParser.hh"
00030 #include "CommandDialog.hh"
00031 #include "fluxbox.hh"
00032
00033 #include "FbTk/SimpleCommand.hh"
00034 #include "FbTk/ImageControl.hh"
00035 #include "FbTk/Menu.hh"
00036 #include "FbTk/MenuItem.hh"
00037
00038 #ifdef HAVE_CONFIG_H
00039 #include "config.h"
00040 #endif // HAVE_CONFIG_H
00041
00042 #include <ctime>
00043 #include <string>
00044 #include <iostream>
00045 using namespace std;
00046
00047 class ClockMenuItem: public FbTk::MenuItem {
00048 public:
00049 explicit ClockMenuItem::ClockMenuItem(ClockTool &tool):
00050 FbTk::MenuItem(""), m_tool(tool) {
00051
00052 if (m_tool.timeFormat().find("%k") != std::string::npos ||
00053 m_tool.timeFormat().find("%H") != std::string::npos ||
00054 m_tool.timeFormat().find("%T") != std::string::npos)
00055 setLabel("Clock: 24h");
00056 else
00057 setLabel("Clock: 12h");
00058 }
00059
00060 void click(int button, int time) {
00061 std::string newformat = m_tool.timeFormat();
00062 size_t pos = newformat.find("%k");
00063 std::string newstr;
00064 bool clock24hour = true;
00065 if (pos != std::string::npos)
00066 newstr = "%l";
00067 else if ((pos = newformat.find("%H")) != std::string::npos)
00068 newstr = "%I";
00069 else if ((pos = newformat.find("%T")) != std::string::npos)
00070 newstr = "%r";
00071
00072
00073 if (newstr.empty()) {
00074 clock24hour = false;
00075 if ((pos = newformat.find("%l")) != std::string::npos)
00076 newstr = "%k";
00077 else if ((pos = newformat.find("%I")) != std::string::npos)
00078 newstr = "%H";
00079 else if ((pos = newformat.find("%r")) != std::string::npos)
00080 newstr = "%T";
00081
00082 }
00083
00084 if (!newstr.empty()) {
00085
00086 newformat.replace(pos, 2, newstr);
00087 if (!clock24hour) {
00088 pos = newformat.find("%p");
00089 if (pos != std::string::npos)
00090 newformat.erase(pos, 2);
00091 else if ((pos = newformat.find("%P")) != std::string::npos)
00092 newformat.erase(pos, 2);
00093 }
00094
00095
00096 m_tool.setTimeFormat(newformat);
00097
00098 if (m_tool.timeFormat().find("%k") != std::string::npos ||
00099 m_tool.timeFormat().find("%H") != std::string::npos ||
00100 m_tool.timeFormat().find("%T") != std::string::npos)
00101 setLabel("Clock: 24h");
00102 else
00103 setLabel("Clock: 12h");
00104
00105 }
00106 FbTk::MenuItem::click(button, time);
00107 }
00108 private:
00109 ClockTool &m_tool;
00110 };
00111
00112 class EditClockFormatCmd: public FbTk::Command {
00113 public:
00114 void execute() {
00115 BScreen *screen = Fluxbox::instance()->mouseScreen();
00116 if (screen == 0)
00117 return;
00118 std::string resourcename = screen->name() + ".strftimeFormat";
00119
00120 CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format",
00121 "SetResourceValue " + resourcename + " ");
00122 FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine("reconfigure"));
00123 dialog->setPostCommand(cmd);
00124 dialog->setText(screen->resourceManager().resourceValue(resourcename));
00125 dialog->show();
00126 }
00127 };
00128
00129 ClockTool::ClockTool(const FbTk::FbWindow &parent,
00130 ToolTheme &theme, BScreen &screen, FbTk::Menu &menu):
00131 ToolbarItem(ToolbarItem::FIXED),
00132 m_button(parent, theme.font(), ""),
00133 m_theme(theme),
00134 m_screen(screen),
00135 m_pixmap(0),
00136 m_timeformat(screen.resourceManager(), std::string("%k:%M"),
00137 screen.name() + ".strftimeFormat", screen.altName() + ".StrftimeFormat") {
00138
00139 theme.reconfigSig().attach(this);
00140
00141
00142 timeval delay;
00143 delay.tv_sec = 1;
00144 delay.tv_usec = 0;
00145 m_timer.setTimeout(delay);
00146 FbTk::RefCount<FbTk::Command> update_graphic(new FbTk::SimpleCommand<ClockTool>(*this,
00147 &ClockTool::updateTime));
00148 m_timer.setCommand(update_graphic);
00149 m_timer.start();
00150
00151 m_button.setGC(m_theme.textGC());
00152
00153
00154 FbTk::RefCount<FbTk::Command> saverc(CommandParser::instance().parseLine("saverc"));
00155 FbTk::MenuItem *item = new ClockMenuItem(*this);
00156 item->setCommand(saverc);
00157 menu.insert(item);
00158 FbTk::RefCount<FbTk::Command> editformat_cmd(new EditClockFormatCmd());
00159 menu.insert("Edit Clock Format", editformat_cmd);
00160
00161
00162 update(0);
00163 }
00164
00165 ClockTool::~ClockTool() {
00166
00167 if (m_pixmap)
00168 m_screen.imageControl().removeImage(m_pixmap);
00169 }
00170
00171 void ClockTool::move(int x, int y) {
00172 m_button.move(x, y);
00173 }
00174
00175 void ClockTool::resize(unsigned int width, unsigned int height) {
00176 m_button.resize(width, height);
00177 renderTheme();
00178 }
00179
00180 void ClockTool::moveResize(int x, int y,
00181 unsigned int width, unsigned int height) {
00182 m_button.moveResize(x, y, width, height);
00183 renderTheme();
00184 }
00185
00186 void ClockTool::show() {
00187 m_button.show();
00188 }
00189
00190 void ClockTool::hide() {
00191 m_button.hide();
00192 }
00193
00194 void ClockTool::setTimeFormat(const std::string &format) {
00195 *m_timeformat = format;
00196 update(0);
00197 }
00198
00199 void ClockTool::update(FbTk::Subject *subj) {
00200 updateTime();
00201
00202
00203 std::string text;
00204 for (size_t i=0; i<m_button.text().size() + 2; ++i)
00205 text += '0';
00206
00207 resize(m_theme.font().textWidth(text.c_str(), text.size()), m_button.height());
00208 }
00209
00210 unsigned int ClockTool::borderWidth() const {
00211 return m_button.borderWidth();
00212 }
00213
00214 unsigned int ClockTool::width() const {
00215 return m_button.width();
00216 }
00217
00218 unsigned int ClockTool::height() const {
00219 return m_button.height();
00220 }
00221
00222 void ClockTool::updateTime() {
00223
00224
00225 time_t the_time = time(0);
00226
00227 if (the_time != -1) {
00228 char time_string[255];
00229 struct tm *time_type = localtime(&the_time);
00230 if (time_type == 0)
00231 return;
00232
00233 #ifdef HAVE_STRFTIME
00234 if (!strftime(time_string, 255, m_timeformat->c_str(), time_type))
00235 return;
00236 m_button.setText(time_string);
00237 #else // dont have strftime so we have to set it to hour:minut
00238
00239 #endif // HAVE_STRFTIME
00240 }
00241
00242 m_button.clear();
00243 m_button.updateTransparent();
00244 }
00245
00246 void ClockTool::renderTheme() {
00247 Pixmap old_pm = m_pixmap;
00248 if (!m_theme.texture().usePixmap()) {
00249 m_pixmap = 0;
00250 m_button.setBackgroundColor(m_theme.texture().color());
00251 } else {
00252 m_pixmap = m_screen.imageControl().renderImage(m_button.width(), m_button.height(), m_theme.texture());
00253 m_button.setBackgroundPixmap(m_pixmap);
00254 }
00255
00256 if (old_pm)
00257 m_screen.imageControl().removeImage(old_pm);
00258
00259 m_button.setJustify(m_theme.justify());
00260 m_button.setBorderWidth(m_theme.border().width());
00261 m_button.setBorderColor(m_theme.border().color());
00262 m_button.setAlpha(m_theme.alpha());
00263 m_button.clear();
00264 m_button.updateTransparent();
00265 }