Ticket #2412: time_pref_net2.patch

File time_pref_net2.patch, 89.0 KB (added by hamish, 13 years ago)
  • src/preferences/time/ntp.cpp

     
     1/*
     2 * Copyright 2004-2009, pinc Software. All Rights Reserved.
     3 * Distributed under the terms of the MIT license.
     4 */
     5
     6#include "ntp.h"
     7
     8#include <errno.h>
     9#include <netdb.h>
     10#include <string.h>
     11#include <stdio.h>
     12#include <stdlib.h>
     13#include <sys/select.h>
     14#include <sys/socket.h>
     15#include <unistd.h>
     16
     17#include <OS.h>
     18
     19
     20/* This structure and its data fields are described in RFC 1305
     21 * "Network Time Protocol (Version 3)" in appendix A.
     22 */
     23
     24struct fixed32 {
     25    int16   integer;
     26    uint16  fraction;
     27
     28    void
     29    SetTo(int16 integer, uint16 fraction = 0)
     30    {
     31        this->integer = htons(integer);
     32        this->fraction = htons(fraction);
     33    }
     34
     35    int16 Integer() { return htons(integer); }
     36    uint16 Fraction() { return htons(fraction); }
     37};
     38
     39struct ufixed64 {
     40    uint32  integer;
     41    uint32  fraction;
     42
     43    void
     44    SetTo(uint32 integer, uint32 fraction = 0)
     45    {
     46        this->integer = htonl(integer);
     47        this->fraction = htonl(fraction);
     48    }
     49
     50    uint32 Integer() { return htonl(integer); }
     51    uint32 Fraction() { return htonl(fraction); }
     52};
     53
     54struct ntp_data {
     55    uint8       mode : 3;
     56    uint8       version : 3;
     57    uint8       leap_indicator : 2;
     58
     59    uint8       stratum;
     60    int8        poll;
     61    int8        precision;  /* in seconds of the nearest power of two */
     62
     63    fixed32     root_delay;
     64    fixed32     root_dispersion;
     65    uint32      root_identifier;
     66
     67    ufixed64    reference_timestamp;
     68    ufixed64    originate_timestamp;
     69    ufixed64    receive_timestamp;
     70    ufixed64    transmit_timestamp;
     71
     72    /* optional authenticator follows (96 bits) */
     73};
     74
     75#define NTP_PORT        123
     76#define NTP_VERSION_3   3
     77
     78enum ntp_leap_warnings {
     79    LEAP_NO_WARNING = 0,
     80    LEAP_LAST_MINUTE_61_SECONDS,
     81    LEAP_LAST_MINUTE_59_SECONDS,
     82    LEAP_CLOCK_NOT_IN_SYNC,
     83};
     84
     85enum ntp_modes {
     86    MODE_RESERVED = 0,
     87    MODE_SYMMETRIC_ACTIVE,
     88    MODE_SYMMETRIC_PASSIVE,
     89    MODE_CLIENT,
     90    MODE_SERVER,
     91    MODE_BROADCAST,
     92    MODE_NTP_CONTROL_MESSAGE,
     93};
     94
     95
     96const uint32 kUTCtoGMT = 12 * 60 * 60;
     97
     98
     99uint32
     100seconds_system_difference(void)
     101{
     102    const uint32 kYear2000 = 3155713200UL;
     103        // that many seconds from year 1900 to 2000.
     104
     105    struct tm tm;
     106    memset(&tm, 0, sizeof(struct tm));
     107    tm.tm_mday = 1;
     108    tm.tm_year = 100;
     109
     110    return kYear2000 - mktime(&tm);
     111}
     112
     113
     114uint32
     115seconds_since_1900()
     116{
     117    return seconds_system_difference() + real_time_clock();
     118}
     119
     120
     121status_t
     122ntp_update_time(const char* hostname, const char** errorString,
     123    int32* errorCode)
     124{
     125    hostent *server = gethostbyname(hostname);
     126
     127    if (server == NULL) {
     128   
     129        *errorString = "Could not contact server";
     130        return B_ENTRY_NOT_FOUND;
     131    }
     132
     133    ntp_data message;
     134    memset(&message, 0, sizeof(ntp_data));
     135
     136    message.leap_indicator = LEAP_CLOCK_NOT_IN_SYNC;
     137    message.version = NTP_VERSION_3;
     138    message.mode = MODE_CLIENT;
     139
     140    message.stratum = 1;    // primary reference
     141    message.precision = -5; // 2^-5 ~ 32-64 Hz precision
     142
     143    message.root_delay.SetTo(1);    // 1 sec
     144    message.root_dispersion.SetTo(1);
     145
     146    message.transmit_timestamp.SetTo(seconds_since_1900());
     147
     148    int connection = socket(AF_INET, SOCK_DGRAM, 0);
     149    if (connection < 0) {
     150        *errorString = "Could not create socket";
     151        *errorCode = errno;
     152        return B_ERROR;
     153    }
     154
     155    struct sockaddr_in address;
     156    address.sin_family = AF_INET;
     157    address.sin_port = htons(NTP_PORT);
     158    address.sin_addr.s_addr = *(uint32 *)server->h_addr_list[0];
     159
     160    if (sendto(connection, (char *)&message, sizeof(ntp_data),
     161            0, (struct sockaddr *)&address, sizeof(address)) < 0) {
     162        *errorString = "Sending request failed";
     163        *errorCode = errno;
     164        return B_ERROR;
     165    }
     166
     167    fd_set waitForReceived;
     168    FD_ZERO(&waitForReceived);
     169    FD_SET(connection, &waitForReceived);
     170
     171    struct timeval timeout;
     172    timeout.tv_sec = 3;
     173    timeout.tv_usec = 0;
     174    // we'll wait 3 seconds for the answer
     175
     176    if (select(connection + 1, &waitForReceived, NULL, NULL, &timeout) <= 0) {
     177        *errorString = "Waiting for answer failed";
     178        *errorCode = errno;
     179        return B_ERROR;
     180    }
     181
     182    message.transmit_timestamp.SetTo(0);
     183
     184    socklen_t addressSize = sizeof(address);
     185    if (recvfrom(connection, (char *)&message, sizeof(ntp_data), 0,
     186            (sockaddr *)&address, &addressSize) < (ssize_t)sizeof(ntp_data)) {
     187        *errorString = "Message receiving failed";
     188        *errorCode = errno;
     189        close(connection);
     190        return B_ERROR;
     191    }
     192
     193    close(connection);
     194
     195    if (message.transmit_timestamp.Integer() == 0) {
     196        *errorString = "Received invalid time";
     197        return B_BAD_VALUE;
     198    }
     199
     200    time_t now = message.transmit_timestamp.Integer() -
     201        seconds_system_difference() + kUTCtoGMT;
     202    set_real_time_clock(now);
     203    return B_OK;
     204}
  • src/preferences/time/Time.h

     
    3131
    3232
    3333#endif  // _TIME_H
    34 
  • src/preferences/time/NetworkTimeView.cpp

     
     1/*
     2 * Copyright 2011, Haiku, Inc. All Rights Reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Hamish Morrison <hamish@lavabit.com>
     7 *      Axel Dörfler <axeld@pinc-software.de>
     8 */
     9 
     10#include "NetworkTimeView.h"
     11
     12#include <stdio.h>
     13#include <string.h>
     14
     15#include <Alert.h>
     16#include <Button.h>
     17#include <CheckBox.h>
     18#include <File.h>
     19#include <FindDirectory.h>
     20#include <ListView.h>
     21#include <Path.h>
     22#include <ScrollView.h>
     23#include <TextControl.h>
     24
     25#include "ntp.h"
     26#include "TimeMessages.h"
     27
     28
     29Settings::Settings()
     30    :
     31    fMessage(kMsgNetworkTimeSettings)
     32{
     33    ResetToDefaults();
     34    Load();
     35}
     36
     37
     38Settings::~Settings()
     39{
     40    Save();
     41}
     42
     43
     44void
     45Settings::AddServer(const char* server)
     46{
     47    if (_GetStringByValue("server", server) == B_ERROR)
     48        fMessage.AddString("server", server);
     49}
     50
     51
     52const char*
     53Settings::GetServer(int32 index) const
     54{
     55    const char* server;
     56    fMessage.FindString("server", index, &server);
     57    return server;
     58}
     59
     60
     61void
     62Settings::RemoveServer(const char* server)
     63{
     64    int32 index = _GetStringByValue("server", server);
     65    if (index != B_ERROR) {
     66        fMessage.RemoveData("server", index);
     67       
     68        int32 count;
     69        fMessage.GetInfo("server", NULL, &count);
     70        if (GetDefaultServer() >= count)
     71            SetDefaultServer(count - 1);
     72    }
     73}
     74
     75
     76void
     77Settings::SetDefaultServer(int32 index)
     78{
     79    if (fMessage.ReplaceInt32("default server", index) != B_OK)
     80        fMessage.AddInt32("default server", index);
     81}
     82
     83
     84int32
     85Settings::GetDefaultServer() const
     86{
     87    int32 index;
     88    fMessage.FindInt32("default server", &index);
     89    return index;
     90}
     91
     92
     93void
     94Settings::SetTryAllServers(bool boolean)
     95{
     96    fMessage.ReplaceBool("try all servers", boolean);
     97}
     98
     99
     100bool
     101Settings::GetTryAllServers() const
     102{
     103    bool boolean;
     104    fMessage.FindBool("try all servers", &boolean);
     105    return boolean;
     106}
     107
     108
     109void
     110Settings::SetSynchronizeAtBoot(bool boolean)
     111{
     112    fMessage.ReplaceBool("synchronize at boot", boolean);
     113}
     114
     115
     116bool
     117Settings::GetSynchronizeAtBoot() const
     118{
     119    bool boolean;
     120    fMessage.FindBool("synchronize at boot", &boolean);
     121    return boolean;
     122}
     123
     124
     125void
     126Settings::ResetServersToDefaults()
     127{
     128    fMessage.RemoveName("server");
     129
     130    fMessage.AddString("server", "pool.ntp.org");
     131    fMessage.AddString("server", "de.pool.ntp.org");
     132    fMessage.AddString("server", "time.nist.gov");
     133
     134    if (fMessage.ReplaceInt32("default server", 0) != B_OK)
     135        fMessage.AddInt32("default server", 0);
     136}
     137
     138
     139void
     140Settings::ResetToDefaults()
     141{
     142    fMessage.MakeEmpty();
     143    ResetServersToDefaults();
     144
     145    fMessage.AddBool("synchronize at boot", true);
     146    fMessage.AddBool("try all servers", true);
     147}
     148
     149
     150void
     151Settings::Revert()
     152{
     153    fMessage = fOldMessage;
     154}
     155
     156
     157bool
     158Settings::SettingsChanged()
     159{
     160    ssize_t oldSize = fOldMessage.FlattenedSize();
     161    ssize_t newSize = fMessage.FlattenedSize();
     162   
     163    if (oldSize != newSize)
     164        return true;
     165
     166    char* oldBytes = new char[oldSize];
     167    fOldMessage.Flatten(oldBytes, oldSize);
     168    char* newBytes = new char[newSize];
     169    fMessage.Flatten(newBytes, newSize);
     170   
     171    int result = memcmp(oldBytes, newBytes, oldSize);   
     172    delete[] oldBytes, newBytes;
     173    if (result != 0)
     174        return true;
     175    else
     176        return false;
     177}
     178
     179
     180status_t
     181Settings::Load()
     182{
     183    status_t status;
     184
     185    BPath path;
     186    if ((status = _GetPath(path)) != B_OK)
     187        return status;
     188
     189    BFile file(path.Path(), B_READ_ONLY);
     190    if ((status = file.InitCheck()) != B_OK)
     191        return status;
     192
     193    BMessage load;
     194    if ((status = load.Unflatten(&file)) != B_OK)
     195        return status;
     196
     197    if (load.what != kMsgNetworkTimeSettings)
     198        return B_BAD_TYPE;
     199
     200    fMessage = load;
     201    fOldMessage = fMessage;
     202    return B_OK;
     203}
     204
     205
     206status_t
     207Settings::Save()
     208{
     209    status_t status;
     210
     211    BPath path;
     212    if ((status = _GetPath(path)) != B_OK)
     213        return status;
     214
     215    BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
     216    if ((status = file.InitCheck()) != B_OK)
     217        return status;
     218
     219    file.SetSize(0);
     220
     221    return fMessage.Flatten(&file);
     222}
     223
     224
     225int32
     226Settings::_GetStringByValue(const char* name, const char* value)
     227{
     228    const char* string;
     229    for (int32 index = 0; fMessage.FindString(
     230        name, index, &string) == B_OK; index++)
     231        if (strcmp(string, value) == 0)
     232            return index;
     233    return B_ERROR;
     234}
     235
     236
     237status_t
     238Settings::_GetPath(BPath& path)
     239{
     240    status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
     241    if (status != B_OK)
     242        return status;
     243    path.Append("pinc.networktime settings");
     244    return B_OK;
     245}
     246
     247
     248NetworkTimeView::NetworkTimeView(const char* name)
     249    :
     250    BGroupView(name, B_VERTICAL, B_USE_DEFAULT_SPACING),
     251    fSettings(),
     252    fUpdateThread(-1)
     253{
     254    fSettings.Load();
     255    _InitView();
     256}
     257
     258
     259void
     260NetworkTimeView::MessageReceived(BMessage* message)
     261{
     262    switch (message->what) {
     263        case kMsgSetDefaultServer:
     264        {
     265            int32 sel = fServerListView->CurrentSelection();
     266            if (sel < 0)
     267                fServerListView->Select(fSettings.GetDefaultServer());
     268            else {
     269                fSettings.SetDefaultServer(sel);
     270                Looper()->PostMessage(new BMessage(kMsgChange));
     271            }
     272            break;
     273        }
     274        case kMsgAddServer:
     275            fSettings.AddServer(fServerTextControl->Text());
     276            _UpdateServerList();
     277            Looper()->PostMessage(new BMessage(kMsgChange));
     278            break;
     279
     280        case kMsgRemoveServer:
     281            fSettings.RemoveServer(((BStringItem*)
     282                fServerListView->ItemAt(
     283                    fServerListView->
     284                    CurrentSelection()))->Text());
     285            _UpdateServerList();
     286            Looper()->PostMessage(new BMessage(kMsgChange));
     287            break;
     288           
     289        case kMsgResetServerList:
     290            fSettings.ResetServersToDefaults();
     291            _UpdateServerList();
     292            Looper()->PostMessage(new BMessage(kMsgChange));
     293            break;
     294       
     295        case kMsgTryAllServers:
     296            fSettings.SetTryAllServers(
     297                fTryAllServersCheckBox->Value());
     298            Looper()->PostMessage(new BMessage(kMsgChange));
     299            break;
     300
     301        case kMsgSynchronizeAtBoot:
     302            fSettings.SetSynchronizeAtBoot(
     303                fSynchronizeAtBootCheckBox->Value());
     304            Looper()->PostMessage(new BMessage(kMsgChange));
     305            break;
     306
     307        case kMsgStopSynchronization:
     308            if (fUpdateThread >= B_OK)
     309                kill_thread(fUpdateThread);
     310            _DoneSynchronizing();
     311            break;
     312
     313        case kMsgSynchronize:
     314        {
     315            if (fUpdateThread >= B_OK)
     316                break;
     317
     318            BMessenger* messenger = new BMessenger(this);
     319            update_time(fSettings, messenger, &fUpdateThread);
     320            fSynchronizeButton->SetLabel("Stop");
     321            fSynchronizeButton->Message()->what = kMsgStopSynchronization;
     322            break;
     323        }
     324
     325        case kMsgSynchronizationResult:
     326        {
     327            _DoneSynchronizing();
     328           
     329            status_t status;
     330            if (message->FindInt32("status", (int32 *)&status) == B_OK) {
     331                if (status == B_OK) return;
     332
     333                const char* errorString;
     334                message->FindString("error string", &errorString); 
     335                char buffer[256];
     336                   
     337                int32 errorCode;
     338                if (message->FindInt32("error code", &errorCode)
     339                    == B_OK)
     340                    snprintf(buffer, sizeof(buffer),
     341                        "The following error occured "
     342                        "while synchronizing:\r\n%s: %s",
     343                        errorString, strerror(errorCode));
     344                else
     345                    snprintf(buffer, sizeof(buffer),
     346                        "The following error occured "
     347                        "while synchronizing:\r\n%s",
     348                        errorString);
     349
     350                (new BAlert("Time", buffer, "OK"))->Go();
     351            }
     352            break;
     353        }
     354       
     355        case kMsgRevert:
     356            fSettings.Revert();
     357            fTryAllServersCheckBox->SetValue(
     358                fSettings.GetTryAllServers());
     359            fSynchronizeAtBootCheckBox->SetValue(
     360                fSettings.GetSynchronizeAtBoot());
     361            _UpdateServerList();
     362            break;
     363    }
     364}
     365
     366
     367void
     368NetworkTimeView::AttachedToWindow()
     369{
     370    fServerListView->SetTarget(this);
     371    fAddButton->SetTarget(this);
     372    fRemoveButton->SetTarget(this);
     373    fResetButton->SetTarget(this);
     374    fTryAllServersCheckBox->SetTarget(this);
     375    fSynchronizeAtBootCheckBox->SetTarget(this);
     376    fSynchronizeButton->SetTarget(this);
     377}
     378
     379
     380bool
     381NetworkTimeView::CheckCanRevert()
     382{
     383    return fSettings.SettingsChanged();
     384}
     385
     386void
     387NetworkTimeView::_InitView()
     388{
     389    fServerTextControl = new BTextControl(NULL, NULL, NULL);
     390
     391    fAddButton = new BButton("add", "Add", new BMessage(kMsgAddServer));
     392    fRemoveButton = new BButton("remove", "Remove",
     393        new BMessage(kMsgRemoveServer));
     394    fResetButton = new BButton("reset", "Reset",
     395        new BMessage(kMsgResetServerList));
     396
     397    fServerListView = new BListView("serverList");
     398    fServerListView->SetSelectionMessage(new
     399        BMessage(kMsgSetDefaultServer));
     400    BScrollView* scrollView = new BScrollView("serverScrollView",
     401        fServerListView, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
     402    _UpdateServerList();
     403   
     404    fTryAllServersCheckBox = new BCheckBox("tryAllServers",
     405        "Try all servers", new BMessage(kMsgTryAllServers));
     406    fTryAllServersCheckBox->SetValue(fSettings.GetTryAllServers());
     407   
     408    fSynchronizeAtBootCheckBox = new BCheckBox("autoUpdate",
     409        "Synchronize at boot", new BMessage(kMsgSynchronizeAtBoot));
     410    fSynchronizeAtBootCheckBox->SetValue(fSettings.GetSynchronizeAtBoot());
     411    fSynchronizeButton = new BButton("update", "Synchronize now",
     412        new BMessage(kMsgSynchronize));
     413    fSynchronizeButton->SetExplicitAlignment(
     414        BAlignment(B_ALIGN_RIGHT, B_ALIGN_BOTTOM));
     415   
     416    BLayoutBuilder::Group<>(this)
     417        .AddGroup(B_HORIZONTAL)
     418            .AddGroup(B_VERTICAL, 0)
     419                .Add(fServerTextControl)
     420                .Add(scrollView)
     421            .End()
     422            .AddGroup(B_VERTICAL)
     423                .Add(fAddButton)
     424                .Add(fRemoveButton)
     425                .Add(fResetButton)
     426                .AddGlue()
     427            .End()
     428        .End()
     429        .AddGroup(B_HORIZONTAL)
     430            .AddGroup(B_VERTICAL)
     431                .Add(fTryAllServersCheckBox)
     432                .Add(fSynchronizeAtBootCheckBox)
     433            .End()
     434            .Add(fSynchronizeButton)
     435        .End()
     436        .SetInsets(5, 5, 5, 5);
     437}
     438
     439
     440void
     441NetworkTimeView::_UpdateServerList()
     442{
     443    while (fServerListView->RemoveItem(0L) != NULL);
     444
     445    const char* server;
     446    int32 index = 0;
     447
     448    while ((server = fSettings.GetServer(index++)) != NULL)
     449        fServerListView->AddItem(new BStringItem(server));
     450
     451    fServerListView->Select(fSettings.GetDefaultServer());
     452    fServerListView->ScrollToSelection();
     453}
     454
     455
     456void
     457NetworkTimeView::_DoneSynchronizing()
     458{
     459    fUpdateThread = -1;
     460    fSynchronizeButton->SetLabel("Synchronize");
     461    fSynchronizeButton->Message()->what = kMsgSynchronize;
     462}
     463
     464
     465status_t
     466update_time(const Settings& settings, const char** errorString,
     467    int32* errorCode)
     468{
     469    int32 defaultServer = settings.GetDefaultServer();
     470
     471    status_t status = B_ENTRY_NOT_FOUND;
     472    const char* server = settings.GetServer(defaultServer);
     473   
     474    if (server != NULL)
     475        status = ntp_update_time(server, errorString, errorCode);
     476
     477    if (status != B_OK && settings.GetTryAllServers()) {
     478        for (int32 index = 0; ; index++) {
     479            if (index == defaultServer)
     480                index++;
     481            server = settings.GetServer(index);
     482            if (server == NULL)
     483                break;
     484
     485            status = ntp_update_time(server, errorString, errorCode);
     486            if (status == B_OK)
     487                break;
     488        }
     489    }
     490   
     491    return status;
     492}
     493
     494
     495int32
     496update_thread(void* params)
     497{
     498    BList* list = (BList*)params;
     499    BMessenger* messenger = (BMessenger*)list->ItemAt(1);
     500
     501    const char* errorString = NULL;
     502    int32 errorCode = 0;
     503    status_t status = update_time(*(Settings*)list->ItemAt(0),
     504        &errorString, &errorCode);
     505
     506    BMessage result(kMsgSynchronizationResult);
     507    result.AddInt32("status", status);
     508    result.AddString("error string", errorString);
     509    if (errorCode != 0)
     510        result.AddInt32("error code", errorCode);
     511    messenger->SendMessage(&result);
     512   
     513    delete messenger;
     514    return B_OK;
     515}
     516
     517
     518status_t
     519update_time(const Settings& settings, BMessenger* messenger,
     520    thread_id* thread)
     521{
     522    BList* params = new BList(2);
     523    params->AddItem((void*)&settings);
     524    params->AddItem((void*)messenger);
     525    *thread = spawn_thread(update_thread, "ntpUpdate", 64, params);
     526    return resume_thread(*thread);
     527}
  • src/preferences/time/TimeZoneListItem.cpp

     
    11/*
    2  * Copyright 2010, Haiku Inc. All rights reserved.
     2 * Copyright 2011, Haiku Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    99 *      Oliver Tappe <zooey@hirschkaefer.de>
    1010*/
    1111
    12 
    1312#include "TimeZoneListItem.h"
    1413
    1514#include <new>
  • src/preferences/time/BaseView.cpp

     
    88 */
    99
    1010#include "BaseView.h"
    11 #include "TimeMessages.h"
    1211
    13 
    1412#include <DateTime.h>
    1513#include <OS.h>
    1614
     15#include "TimeMessages.h"
    1716
    18 TTimeBaseView::TTimeBaseView(BRect frame, const char* name)
    19     : BView(frame, name, B_FOLLOW_NONE, B_PULSE_NEEDED),
    20       fMessage(H_TIME_UPDATE)
     17
     18TTimeBaseView::TTimeBaseView(const char* name)
     19    :
     20    BGroupView(name, B_VERTICAL, 0),
     21    fMessage(H_TIME_UPDATE)
    2122{
     23    SetFlags(Flags() | B_PULSE_NEEDED);
    2224}
    2325
    2426
     
    108110
    109111    SendNotices(H_TM_CHANGED, &fMessage);
    110112}
    111 
  • src/preferences/time/ZoneView.cpp

     
    88 *      Philippe Saint-Pierre <stpere@gmail.com>
    99 *      Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
    1010 *      Oliver Tappe <zooey@hirschkaefer.de>
     11 *      Hamish Morrison <hamish@lavabit.com>
    1112 */
    1213
    13 
    1414#include "ZoneView.h"
    1515
    1616#include <stdlib.h>
     17#include <syscalls.h>
    1718
    1819#include <map>
    1920#include <new>
     
    3637#include <StorageDefs.h>
    3738#include <String.h>
    3839#include <TimeZone.h>
     40#include <ToolTip.h>
    3941#include <View.h>
    4042#include <Window.h>
    4143
    42 #include <syscalls.h>
    43 #include <ToolTip.h>
    44 
    4544#include <unicode/datefmt.h>
    4645#include <unicode/utmscale.h>
    4746#include <ICUWrapper.h>
     
    4948#include "TimeMessages.h"
    5049#include "TimeZoneListItem.h"
    5150#include "TZDisplay.h"
    52 #include "TimeWindow.h"
    5351
    5452
    5553#undef B_TRANSLATE_CONTEXT
     
    7775
    7876
    7977
    80 TimeZoneView::TimeZoneView(BRect frame)
     78TimeZoneView::TimeZoneView(const char* name)
    8179    :
    82     BView(frame, "timeZoneView", B_FOLLOW_NONE, B_WILL_DRAW | B_NAVIGABLE_JUMP),
     80    BGroupView(name, B_HORIZONTAL, B_USE_DEFAULT_SPACING),
    8381    fToolTip(NULL),
    8482    fCurrentZoneItem(NULL),
    8583    fOldZoneItem(NULL),
     
    159157        case H_SET_TIME_ZONE:
    160158        {
    161159            _SetSystemTimeZone();
    162             ((TTimeWindow*)Window())->SetRevertStatus();
     160            Looper()->PostMessage(new BMessage(kMsgChange));
    163161            break;
    164162        }
    165163
     
    173171            break;
    174172
    175173        default:
    176             BView::MessageReceived(message);
     174            BGroupView::MessageReceived(message);
    177175            break;
    178176    }
    179177}
     
    233231void
    234232TimeZoneView::_InitView()
    235233{
    236     // left side
    237     BRect frameLeft(Bounds());
    238     frameLeft.right = frameLeft.Width() / 2.0;
    239     frameLeft.InsetBy(10.0f, 10.0f);
    240 
    241     // City Listing
    242     fZoneList = new BOutlineListView(frameLeft, "cityList",
    243         B_SINGLE_SELECTION_LIST);
     234    fZoneList = new BOutlineListView("cityList", B_SINGLE_SELECTION_LIST);
    244235    fZoneList->SetSelectionMessage(new BMessage(H_CITY_CHANGED));
    245236    fZoneList->SetInvocationMessage(new BMessage(H_SET_TIME_ZONE));
    246 
    247237    _BuildZoneMenu();
    248 
    249238    BScrollView* scrollList = new BScrollView("scrollList", fZoneList,
    250         B_FOLLOW_ALL, 0, false, true);
    251     AddChild(scrollList);
     239        B_FRAME_EVENTS | B_WILL_DRAW, false, true);
    252240
    253     // right side
    254     BRect frameRight(Bounds());
    255     frameRight.left = frameRight.Width() / 2.0;
    256     frameRight.InsetBy(10.0f, 10.0f);
    257     frameRight.top = frameLeft.top;
     241    fCurrent = new TTZDisplay("currentTime", B_TRANSLATE("Current time:"));
     242    fPreview = new TTZDisplay("previewTime", B_TRANSLATE("Preview time:"));
    258243
    259     // Time Displays
    260     fCurrent = new TTZDisplay(frameRight, "currentTime",
    261         B_TRANSLATE("Current time:"));
    262     AddChild(fCurrent);
    263     fCurrent->ResizeToPreferred();
    264 
    265     frameRight.top = fCurrent->Frame().bottom + 10.0;
    266     fPreview = new TTZDisplay(frameRight, "previewTime",
    267         B_TRANSLATE("Preview time:"));
    268     AddChild(fPreview);
    269     fPreview->ResizeToPreferred();
    270 
    271     // set button
    272     fSetZone = new BButton(frameRight, "setTimeZone",
    273         B_TRANSLATE("Set time zone"),
     244    fSetZone = new BButton("setTimeZone", B_TRANSLATE("Set time zone"),
    274245        new BMessage(H_SET_TIME_ZONE));
    275     AddChild(fSetZone);
    276246    fSetZone->SetEnabled(false);
    277     fSetZone->ResizeToPreferred();
    278 
    279     fSetZone->MoveTo(frameRight.right - fSetZone->Bounds().Width(),
    280         scrollList->Frame().bottom - fSetZone->Bounds().Height());
     247    fSetZone->SetExplicitAlignment(
     248        BAlignment(B_ALIGN_RIGHT, B_ALIGN_BOTTOM));
     249   
     250    BLayoutBuilder::Group<>(this)
     251        .Add(scrollList)
     252        .AddGroup(B_VERTICAL, 5)
     253            .Add(fCurrent)
     254            .Add(fPreview)
     255            .AddGlue()
     256            .Add(fSetZone)
     257        .End()
     258        .SetInsets(5, 5, 5, 5);
    281259}
    282260
    283261
     
    336314
    337315            BString region(zoneID, slashPos);
    338316
    339             if (region == "Etc")
     317            if (region == B_TRANSLATE("Etc"))
    340318                region = kOtherRegion;
    341319            else if (countryName.Length() == 0) {
    342320                // skip global timezones from other regions, we are just
  • src/preferences/time/DateTimeEdit.h

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      McCall <mccall@@digitalparadise.co.uk>
    77 *      Mike Berg <mike@berg-net.us>
    88 *      Julun <host.haiku@gmx.de>
    9  *
     9 *      Hamish Morrison <hamish@lavabit.com>
    1010 */
    1111#ifndef _DATE_TIME_EDIT_H
    1212#define _DATE_TIME_EDIT_H
    1313
    1414
    15 #include "SectionEdit.h"
    16 
    1715#include <DateTime.h>
    1816#include <Locale.h>
    1917#include <String.h>
    2018
     19#include "SectionEdit.h"
    2120
     21
    2222class TTimeEdit : public TSectionEdit {
    2323public:
    24                                 TTimeEdit(BRect frame, const char* name,
    25                                     uint32 sections);
     24                                TTimeEdit(const char* name, uint32 sections);
    2625    virtual                     ~TTimeEdit();
    2726
    2827    virtual void                KeyDown(const char* bytes, int32 numBytes);
    2928
    3029    virtual void                InitView();
    31     virtual void                DrawSection(uint32 index, bool isfocus);
    32     virtual void                DrawSeparator(uint32 index);
     30    virtual void                DrawSection(uint32 index, BRect bounds,
     31                                    bool isfocus);
     32    virtual void                DrawSeparator(uint32 index, BRect bounds);
    3333
    34     virtual void                SetSections(BRect area);
    3534    virtual void                SectionFocus(uint32 index);
    36     virtual float               SeparatorWidth() const;
     35    virtual float               MinSectionWidth();
     36    virtual float               SeparatorWidth();
    3737
     38    virtual float               PreferredHeight();
    3839    virtual void                DoUpPress();
    3940    virtual void                DoDownPress();
    4041
     
    4849            bool                _IsValidDoubleDigit(int32 value);
    4950            int32               _SectionValue(int32 index) const;
    5051
    51 private:
    5252            BDateTime           fTime;
    5353            bigtime_t           fLastKeyDownTime;
    5454            int32               fLastKeyDownInt;
     
    6565
    6666class TDateEdit : public TSectionEdit {
    6767public:
    68                                 TDateEdit(BRect frame, const char* name,
    69                                     uint32 sections);
     68                                TDateEdit(const char* name, uint32 sections);
    7069    virtual                     ~TDateEdit();
    7170    virtual void                KeyDown(const char* bytes, int32 numBytes);
    7271
    7372    virtual void                InitView();
    74     virtual void                DrawSection(uint32 index, bool isfocus);
    75     virtual void                DrawSeparator(uint32 index);
     73    virtual void                DrawSection(uint32 index, BRect bounds,
     74                                    bool isfocus);
     75    virtual void                DrawSeparator(uint32 index, BRect bounds);
    7676
    77     virtual void                SetSections(BRect area);
    7877    virtual void                SectionFocus(uint32 index);
    79     virtual float               SeparatorWidth() const;
     78    virtual float               MinSectionWidth();
     79    virtual float               SeparatorWidth();
    8080
     81    virtual float               PreferredHeight();
    8182    virtual void                DoUpPress();
    8283    virtual void                DoDownPress();
    8384
    8485    virtual void                BuildDispatch(BMessage* message);
     86   
    8587
    8688            void                SetDate(int32 year, int32 month, int32 day);
    8789
     
    9092            void                _CheckRange();
    9193            bool                _IsValidDoubleDigit(int32 value);
    9294            int32               _SectionValue(int32 index) const;
    93 
    94 private:
     95           
    9596            BDate               fDate;
    9697            bigtime_t           fLastKeyDownTime;
    9798            int32               fLastKeyDownInt;
     
    107108
    108109
    109110#endif  // _DATE_TIME_EDIT_H
    110 
  • src/preferences/time/SectionEdit.cpp

     
    11/*
    2  * Copyright 2004-2007, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Mike Berg <mike@berg-net.us>
    77 *      Julun <host.haiku@gmx.de>
    8  *
     8 *      Hamish Morrison <hamish@lavabit.com>
    99 */
    1010
    11 
    1211#include "SectionEdit.h"
    1312
    1413#include <Bitmap.h>
    1514#include <ControlLook.h>
     15#include <LayoutUtils.h>
    1616#include <List.h>
    1717#include <Window.h>
    1818
    1919#include "TimeMessages.h"
    2020
    2121
    22 TSection::TSection(BRect frame)
    23     :
    24     fFrame(frame)
    25 {
    26 }
    27 
    28 
    29 BRect
    30 TSection::Bounds() const
    31 {
    32     BRect frame(fFrame);
    33     return frame.OffsetByCopy(B_ORIGIN);
    34 }
    35 
    36 
    37 void
    38 TSection::SetFrame(BRect frame)
    39 {
    40     fFrame = frame;
    41 }
    42 
    43 
    44 BRect
    45 TSection::Frame() const
    46 {
    47     return fFrame;
    48 }
    49 
    50 
    5122const uint32 kArrowAreaWidth = 16;
    5223
    5324
    54 TSectionEdit::TSectionEdit(BRect frame, const char* name, uint32 sections)
     25TSectionEdit::TSectionEdit(const char* name, uint32 sections)
    5526    :
    56     BControl(frame, name, NULL, NULL, B_FOLLOW_NONE, B_NAVIGABLE | B_WILL_DRAW),
    57     fSectionList(NULL),
     27    BControl(name, NULL, NULL, B_WILL_DRAW | B_NAVIGABLE),
    5828    fFocus(-1),
    5929    fSectionCount(sections),
    6030    fHoldValue(0)
    6131{
    62     InitView();
    6332}
    6433
    6534
    6635TSectionEdit::~TSectionEdit()
    6736{
    68     int32 count = fSectionList->CountItems();
    69     if (count > 0) {
    70         for (int32 index = 0; index < count; index++)
    71             delete (TSection*)fSectionList->ItemAt(index);
    72     }
    73     delete fSectionList;
    7437}
    7538
    7639
     
    8851    DrawBorder(updateRect);
    8952
    9053    for (uint32 idx = 0; idx < fSectionCount; idx++) {
    91         DrawSection(idx, ((uint32)fFocus == idx) && IsFocus());
     54        DrawSection(idx, FrameForSection(idx),
     55            ((uint32)fFocus == idx) && IsFocus());
    9256        if (idx < fSectionCount - 1)
    93             DrawSeparator(idx);
     57            DrawSeparator(idx, FrameForSeparator(idx));
    9458    }
    9559}
    9660
     
    10468        DoUpPress();
    10569    else if (fDownRect.Contains(where))
    10670        DoDownPress();
    107     else if (fSectionList->CountItems() > 0) {
    108         TSection* section;
     71    else if (fSectionCount > 0) {
    10972        for (uint32 idx = 0; idx < fSectionCount; idx++) {
    110             section = (TSection*)fSectionList->ItemAt(idx);
    111             if (section->Frame().Contains(where)) {
     73            if (FrameForSection(idx).Contains(where)) {
    11274                SectionFocus(idx);
    11375                return;
    11476            }
     
    11779}
    11880
    11981
     82BSize
     83TSectionEdit::MaxSize()
     84{
     85    return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
     86        BSize(B_SIZE_UNLIMITED, PreferredHeight()));
     87}
     88
     89
     90BSize
     91TSectionEdit::MinSize()
     92{
     93    BSize minSize;
     94    minSize.height = PreferredHeight();
     95    minSize.width = (SeparatorWidth() + MinSectionWidth())
     96        * fSectionCount;
     97    return BLayoutUtils::ComposeSize(ExplicitMinSize(),
     98        minSize);
     99}
     100
     101
     102BSize
     103TSectionEdit::PreferredSize()
     104{
     105    return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
     106        MinSize());
     107}
     108
     109
     110BRect
     111TSectionEdit::FrameForSection(uint32 index)
     112{
     113    BRect area = SectionArea();
     114    float sepWidth = SeparatorWidth();
     115   
     116    float width = (area.Width() -
     117        sepWidth * (fSectionCount - 1))
     118        / fSectionCount;
     119    area.left += index * (width + sepWidth);
     120    area.right = area.left + width;
     121
     122    return area;
     123}
     124
     125
     126BRect
     127TSectionEdit::FrameForSeparator(uint32 index)
     128{
     129    BRect area = SectionArea();
     130    float sepWidth = SeparatorWidth();
     131
     132    float width = (area.Width() -
     133        sepWidth * (fSectionCount - 1))
     134        / fSectionCount;
     135    area.left += (index + 1) * width + index * sepWidth;
     136    area.right = area.left + sepWidth;
     137
     138    return area;
     139}
     140
     141
    120142void
    121143TSectionEdit::MakeFocus(bool focused)
    122144{
     
    181203uint32
    182204TSectionEdit::CountSections() const
    183205{
    184     return fSectionList->CountItems();
     206    return fSectionCount;
    185207}
    186208
    187209
     
    192214}
    193215
    194216
    195 void
    196 TSectionEdit::InitView()
     217BRect
     218TSectionEdit::SectionArea() const
    197219{
    198     // setup sections
    199     fSectionList = new BList(fSectionCount);
    200     fSectionArea = Bounds().InsetByCopy(2, 2);
    201     fSectionArea.right -= kArrowAreaWidth;
     220    BRect sectionArea = Bounds().InsetByCopy(2, 2);
     221    sectionArea.right -= kArrowAreaWidth;
     222    return sectionArea;
    202223}
    203224
    204225
     
    219240        bounds.bottom / 2.0);
    220241    fDownRect = fUpRect.OffsetByCopy(0, fUpRect.Height() + 2);
    221242
    222     BPoint middle(floorf(fUpRect.left + fUpRect.Width() / 2), fUpRect.top + 1);
     243    BPoint middle(floorf(fUpRect.left + fUpRect.Width() / 2),
     244        fUpRect.top + 1);
    223245    BPoint left(fUpRect.left + 3, fUpRect.bottom - 1);
    224246    BPoint right(left.x + 2 * (middle.x - left.x), fUpRect.bottom - 1);
    225247
    226248    SetPenSize(2);
     249    SetLowColor(ViewColor());
    227250
    228251    if (updateRect.Intersects(fUpRect)) {
    229252        FillRect(fUpRect, B_SOLID_LOW);
     
    245268
    246269    SetPenSize(1);
    247270}
    248 
    249 
    250 float
    251 TSectionEdit::SeparatorWidth() const
    252 {
    253     return 0.0f;
    254 }
  • src/preferences/time/TimeSettings.cpp

     
    1919
    2020
    2121TimeSettings::TimeSettings()
    22     : fSettingsFile("Time_preflet_window")
     22    :
     23    fSettingsFile("Time_preflet_window")
    2324{
    2425}
    2526
     
    6364    if (file.InitCheck() == B_OK)
    6465        file.Write(&leftTop, sizeof(BPoint));
    6566}
    66 
  • src/preferences/time/AnalogClock.h

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Mike Berg <mike@berg-net.us>
    77 *      Julun <host.haiku@gmx.de>
     8 *      Hamish Morrison <hamish@lavabit.com>
    89 */
    910#ifndef _ANALOG_CLOCK_H
    1011#define _ANALOG_CLOCK_H
     
    1314#include <View.h>
    1415
    1516
    16 class BBitmap;
    17 class OffscreenClock;
    18 
    19 
    2017class TAnalogClock : public BView {
    2118public:
    22                                 TAnalogClock(BRect frame, const char* name,
    23                                     bool drawSecondHand = true, bool interactive = true);
    24     virtual                     ~TAnalogClock();
     19                            TAnalogClock(const char* name,
     20                                bool drawSecondHand = true,
     21                                bool interactive = true);
     22    virtual                 ~TAnalogClock();
    2523
    26     virtual void                AttachedToWindow();
    27     virtual void                Draw(BRect updateRect);
    28     virtual void                MessageReceived(BMessage* message);
    29     virtual void                MouseDown(BPoint point);
    30     virtual void                MouseUp(BPoint point);
    31     virtual void                MouseMoved(BPoint point, uint32 transit,
    32                                     const BMessage* message);
     24    virtual void            Draw(BRect updateRect);
     25    virtual void            MessageReceived(BMessage* message);
     26    virtual void            MouseDown(BPoint point);
     27    virtual void            MouseUp(BPoint point);
     28    virtual void            MouseMoved(BPoint point, uint32 transit,
     29                                const BMessage* message);
     30    virtual void            FrameResized(float, float);
     31   
     32    virtual BSize           MaxSize();
     33    virtual BSize           MinSize();
     34    virtual BSize           PreferredSize();
    3335
    34             void                SetTime(int32 hour, int32 minute, int32 second);
     36            void            SetTime(int32 hour, int32 minute, int32 second);
     37            bool            IsChangingTime();
     38            void            ChangeTimeFinished();
    3539
    36             bool                IsChangingTime()
    37                                     {   return fTimeChangeIsOngoing;    }
    38             void                ChangeTimeFinished();
     40            void            GetTime(int32* hour, int32* minute, int32* second);
     41            void            DrawClock();
     42
     43            bool            InHourHand(BPoint point);
     44            bool            InMinuteHand(BPoint point);
     45
     46            void            SetHourHand(BPoint point);
     47            void            SetMinuteHand(BPoint point);
     48
     49            void            SetHourDragging(bool dragging);
     50            void            SetMinuteDragging(bool dragging);
    3951private:
    40             void                _InitView(BRect frame);
     52            float           _GetPhi(BPoint point);
     53            bool            _InHand(BPoint point, int32 ticks, float radius);
     54            void            _DrawHands(float x, float y, float radius,
     55                                rgb_color hourHourColor,
     56                                rgb_color hourMinuteColor,
     57                                rgb_color secondsColor, rgb_color knobColor);
    4158
    42             BBitmap*            fBitmap;
    43             OffscreenClock*     fClock;
     59            int32           fHours;
     60            int32           fMinutes;
     61            int32           fSeconds;
     62            bool            fDirty;
     63           
     64            float           fCenterX;
     65            float           fCenterY;
     66            float           fRadius;
    4467
    45             bool                fDrawSecondHand;
    46             bool                fInteractive;
    47             bool                fDraggingHourHand;
    48             bool                fDraggingMinuteHand;
     68            bool            fHourDragging;
     69            bool            fMinuteDragging;
     70            bool            fDrawSecondHand;
     71            bool            fInteractive;
    4972
    50             bool                fTimeChangeIsOngoing;
     73            bool            fTimeChangeIsOngoing;   
    5174};
    5275
    5376
  • src/preferences/time/TimeWindow.cpp

     
    11/*
    2  * Copyright 2004-2007, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Andrew McCall <mccall@@digitalparadise.co.uk>
    77 *      Julun <host.haiku@gmx.de>
    8  *
     8 *      Hamish Morrison <hamish@lavabit.com>
    99 */
    1010
    1111#include "TimeWindow.h"
    12 #include "BaseView.h"
    13 #include "DateTimeView.h"
    14 #include "TimeMessages.h"
    15 #include "TimeSettings.h"
    16 #include "ZoneView.h"
    1712
    18 
    1913#include <Application.h>
     14#include <Button.h>
    2015#include <Catalog.h>
     16#include <LayoutBuilder.h>
    2117#include <Message.h>
    2218#include <Screen.h>
    2319#include <TabView.h>
    24 #include <Button.h>
    2520
     21#include "BaseView.h"
     22#include "DateTimeView.h"
     23#include "NetworkTimeView.h"
     24#include "TimeMessages.h"
     25#include "TimeSettings.h"
     26#include "ZoneView.h"
     27
     28
    2629#undef B_TRANSLATE_CONTEXT
    2730#define B_TRANSLATE_CONTEXT "Time"
    2831
    29 TTimeWindow::TTimeWindow(BRect rect)
    30     : BWindow(rect, B_TRANSLATE("Time"), B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
     32
     33TTimeWindow::TTimeWindow()
     34    :
     35    BWindow(BRect(0, 0, 0, 0), B_TRANSLATE("Time"), B_TITLED_WINDOW,
     36        B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)
    3137{
    3238    _InitWindow();
    3339    _AlignWindow();
     
    4147}
    4248
    4349
    44 void
    45 TTimeWindow::SetRevertStatus()
     50bool
     51TTimeWindow::QuitRequested()
    4652{
    47     fRevertButton->SetEnabled(fDateTimeView->CheckCanRevert()
    48         || fTimeZoneView->CheckCanRevert());
     53    TimeSettings().SetLeftTop(Frame().LeftTop());
     54
     55    fBaseView->StopWatchingAll(fTimeZoneView);
     56    fBaseView->StopWatchingAll(fDateTimeView);
     57
     58    be_app->PostMessage(B_QUIT_REQUESTED);
     59
     60    return BWindow::QuitRequested();
    4961}
    5062
    5163
     
    5769            fBaseView->ChangeTime(message);
    5870            // To make sure no old time message is in the queue
    5971            _SendTimeChangeFinished();
    60             SetRevertStatus();
     72            _SetRevertStatus();
    6173            break;
    6274
    6375        case B_ABOUT_REQUESTED:
     
    6779        case kMsgRevert:
    6880            fDateTimeView->MessageReceived(message);
    6981            fTimeZoneView->MessageReceived(message);
     82            fNetworkTimeView->MessageReceived(message);
    7083            fRevertButton->SetEnabled(false);
    7184            break;
    7285
    7386        case kRTCUpdate:
    7487            fDateTimeView->MessageReceived(message);
    7588            fTimeZoneView->MessageReceived(message);
    76             SetRevertStatus();
     89            _SetRevertStatus();
    7790            break;
    7891
     92        case kMsgChange:
     93            _SetRevertStatus();
     94            break;
     95
    7996        default:
    8097            BWindow::MessageReceived(message);
    8198            break;
     
    83100}
    84101
    85102
    86 bool
    87 TTimeWindow::QuitRequested()
    88 {
    89     TimeSettings().SetLeftTop(Frame().LeftTop());
    90 
    91     fBaseView->StopWatchingAll(fTimeZoneView);
    92     fBaseView->StopWatchingAll(fDateTimeView);
    93 
    94     be_app->PostMessage(B_QUIT_REQUESTED);
    95 
    96     return BWindow::QuitRequested();
    97 }
    98 
    99 
    100103void
    101104TTimeWindow::_InitWindow()
    102105{
    103106    SetPulseRate(500000);
    104107
    105     fDateTimeView = new DateTimeView(Bounds());
     108    fDateTimeView = new DateTimeView(B_TRANSLATE("Date and time"));
     109    fTimeZoneView = new TimeZoneView(B_TRANSLATE("Time zone"));
     110    fNetworkTimeView = new NetworkTimeView(B_TRANSLATE("Network time"));
    106111
    107     BRect bounds = fDateTimeView->Bounds();
    108     fTimeZoneView = new TimeZoneView(bounds);
    109 
    110     fBaseView = new TTimeBaseView(bounds, "baseView");
    111     AddChild(fBaseView);
    112 
     112    fBaseView = new TTimeBaseView("baseView");
    113113    fBaseView->StartWatchingAll(fDateTimeView);
    114114    fBaseView->StartWatchingAll(fTimeZoneView);
    115115
    116     bounds.OffsetBy(10.0, 10.0);
    117     BTabView* tabView = new BTabView(bounds.InsetByCopy(-5.0, -5.0),
    118         "tabView" , B_WIDTH_AS_USUAL, B_FOLLOW_NONE);
    119 
    120     BTab* tab = new BTab();
    121     tabView->AddTab(fDateTimeView, tab);
    122     tab->SetLabel(B_TRANSLATE("Date & Time"));
    123 
    124     tab = new BTab();
    125     tabView->AddTab(fTimeZoneView, tab);
    126     tab->SetLabel(B_TRANSLATE("Time zone"));
    127 
     116    BTabView* tabView = new BTabView("tabView");
     117    tabView->AddTab(fDateTimeView);
     118    tabView->AddTab(fTimeZoneView);
     119    tabView->AddTab(fNetworkTimeView);
     120   
    128121    fBaseView->AddChild(tabView);
    129     tabView->ResizeBy(0.0, tabView->TabHeight());
    130122
    131     BRect rect = Bounds();
    132 
    133     rect.left = 10;
    134     rect.top = rect.bottom - 10;
    135 
    136     fRevertButton = new BButton(rect, "revert", B_TRANSLATE("Revert"),
    137         new BMessage(kMsgRevert), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
    138 
    139     fRevertButton->ResizeToPreferred();
     123    fRevertButton = new BButton("revert", B_TRANSLATE("Revert"),
     124        new BMessage(kMsgRevert));
    140125    fRevertButton->SetEnabled(false);
    141     float buttonHeight = fRevertButton->Bounds().Height();
    142     fRevertButton->MoveBy(0, -buttonHeight);
    143     fBaseView->AddChild(fRevertButton);
    144126    fRevertButton->SetTarget(this);
    145 
    146     fBaseView->ResizeTo(tabView->Bounds().Width() + 10.0,
    147         tabView->Bounds().Height() + buttonHeight + 30.0);
    148 
    149     ResizeTo(fBaseView->Bounds().Width(), fBaseView->Bounds().Height());
     127    fRevertButton->SetExplicitAlignment(
     128        BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE));
     129   
     130    BLayoutBuilder::Group<>(this, B_VERTICAL, 5)
     131        .Add(fBaseView)
     132        .Add(fRevertButton)
     133        .SetInsets(5, 5, 5, 5);
    150134}
    151135
    152136
     
    175159    BMessage msg(kChangeTimeFinished);
    176160    messenger.SendMessage(&msg);
    177161}
     162
     163
     164void
     165TTimeWindow::_SetRevertStatus()
     166{
     167    fRevertButton->SetEnabled(fDateTimeView->CheckCanRevert()
     168        || fTimeZoneView->CheckCanRevert()
     169        || fNetworkTimeView->CheckCanRevert());
     170}
  • src/preferences/time/Jamfile

     
    1212    DateTimeEdit.cpp
    1313    SectionEdit.cpp
    1414    DateTimeView.cpp
     15    NetworkTimeView.cpp
     16    ntp.cpp
    1517    Time.cpp
    1618    TimeSettings.cpp
    1719    TimeWindow.cpp
     
    2830
    2931Preference Time
    3032    : $(sources)
    31     : be libshared.a $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS)
     33    : be libshared.a $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS) $(HAIKU_NETWORK_LIBS)
    3234    : Time.rdef
    3335    ;
    3436
  • src/preferences/time/DateTimeView.cpp

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    77 *      Mike Berg <mike@berg-net.us>
    88 *      Julun <host.haiku@gmx.de>
    99 *      Philippe Saint-Pierre <stpere@gmail.com>
     10 *      Hamish Morrison <hamish@lavabit.com>
    1011 */
    1112
    1213#include "DateTimeView.h"
    13 #include "AnalogClock.h"
    14 #include "DateTimeEdit.h"
    15 #include "TimeMessages.h"
    16 #include "TimeWindow.h"
    1714
     15#include <time.h>
     16#include <syscalls.h>
     17
     18#include <Box.h>
    1819#include <CalendarView.h>
    1920#include <Catalog.h>
    2021#include <CheckBox.h>
     
    2526#include <Message.h>
    2627#include <Path.h>
    2728#include <RadioButton.h>
    28 #include <String.h>
    2929#include <StringView.h>
    3030#include <Window.h>
    3131
    32 #include <time.h>
     32#include "AnalogClock.h"
     33#include "DateTimeEdit.h"
     34#include "TimeMessages.h"
     35#include "TimeWindow.h"
    3336
    34 #include <syscalls.h>
    3537
    3638#undef B_TRANSLATE_CONTEXT
    3739#define B_TRANSLATE_CONTEXT "Time"
     
    4244using BPrivate::B_LOCAL_TIME;
    4345
    4446
    45 DateTimeView::DateTimeView(BRect frame)
    46     : BView(frame, "dateTimeView", B_FOLLOW_NONE, B_WILL_DRAW
    47         | B_NAVIGABLE_JUMP),
     47DateTimeView::DateTimeView(const char* name)
     48    :
     49    BGroupView(name, B_HORIZONTAL, 5),
    4850    fGmtTime(NULL),
    4951    fUseGmtTime(false),
    5052    fInitialized(false),
     
    208210void
    209211DateTimeView::_InitView()
    210212{
    211     font_height fontHeight;
    212     be_plain_font->GetHeight(&fontHeight);
    213     float textHeight = fontHeight.descent + fontHeight.ascent
    214         + fontHeight.leading + 6.0; // 6px border
    215 
    216     // left side
    217     BRect bounds = Bounds();
    218     bounds.InsetBy(10.0, 10.0);
    219     bounds.top += textHeight + 10.0;
    220 
    221     fCalendarView = new BCalendarView(bounds, "calendar");
     213    fCalendarView = new BCalendarView("calendar");
    222214    fCalendarView->SetWeekNumberHeaderVisible(false);
    223     fCalendarView->ResizeToPreferred();
    224215    fCalendarView->SetSelectionMessage(new BMessage(kDayChanged));
    225216    fCalendarView->SetInvocationMessage(new BMessage(kDayChanged));
    226217
    227     bounds.top -= textHeight + 10.0;
    228     bounds.bottom = bounds.top + textHeight;
    229     bounds.right = fCalendarView->Frame().right;
    230 
    231     fDateEdit = new TDateEdit(bounds, "dateEdit", 3);
    232     AddChild(fDateEdit);
    233     AddChild(fCalendarView);
    234 
    235     // right side, 2px extra for separator
    236     bounds.OffsetBy(bounds.Width() + 22.0, 0.0);
    237     fTimeEdit = new TTimeEdit(bounds, "timeEdit", 4);
    238     AddChild(fTimeEdit);
    239 
    240     bounds = fCalendarView->Frame();
    241     bounds.OffsetBy(bounds.Width() + 22.0, 0.0);
    242 
    243     fClock = new TAnalogClock(bounds, "analogClock");
    244     AddChild(fClock);
     218    fDateEdit = new TDateEdit("dateEdit", 3);
     219    fTimeEdit = new TTimeEdit("timeEdit", 4);
     220    fClock = new TAnalogClock("analogClock");
     221   
    245222    BTime time(BTime::CurrentTime(B_LOCAL_TIME));
    246223    fClock->SetTime(time.Hour(), time.Minute(), time.Second());
    247224
    248     // clock radio buttons
    249     bounds.top = fClock->Frame().bottom + 10.0;
    250     BStringView* text = new BStringView(bounds, "clockSetTo",
     225    BStringView* text = new BStringView("clockSetTo",
    251226        B_TRANSLATE("Clock set to:"));
    252     AddChild(text);
    253     text->ResizeToPreferred();
    254 
    255     bounds.left += 10.0f;
    256     bounds.top = text->Frame().bottom;
    257     fLocalTime = new BRadioButton(bounds, "localTime",
     227    fLocalTime = new BRadioButton("localTime",
    258228        B_TRANSLATE("Local time"), new BMessage(kRTCUpdate));
    259     AddChild(fLocalTime);
    260     fLocalTime->ResizeToPreferred();
     229    fGmtTime = new BRadioButton("greenwichMeanTime",
     230        B_TRANSLATE("GMT"), new BMessage(kRTCUpdate));
    261231
    262     bounds.left = fLocalTime->Frame().right + 10.0;
    263     fGmtTime = new BRadioButton(bounds, "greenwichMeanTime",
    264         B_TRANSLATE("GMT"), new BMessage(kRTCUpdate));
    265     AddChild(fGmtTime);
    266     fGmtTime->ResizeToPreferred();
    267 
    268232    if (fUseGmtTime)
    269233        fGmtTime->SetValue(B_CONTROL_ON);
    270234    else
    271235        fLocalTime->SetValue(B_CONTROL_ON);
    272 
    273236    fOldUseGmtTime = fUseGmtTime;
    274237
    275     ResizeTo(fClock->Frame().right + 10.0, fGmtTime->Frame().bottom + 10.0);
     238    BBox* divider = new BBox(BRect(0, 0, 1, 1),
     239        B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,
     240        B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);
     241    divider->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED));
     242
     243    BLayoutBuilder::Group<>(this)
     244        .AddGroup(B_VERTICAL, 5)
     245            .Add(fDateEdit)
     246            .Add(fCalendarView)
     247        .End()
     248        .Add(divider)
     249        .AddGroup(B_VERTICAL, 5)
     250            .Add(fTimeEdit)
     251            .Add(fClock)
     252            .Add(text)
     253            .AddGroup(B_HORIZONTAL, 5)
     254                .Add(fLocalTime)
     255                .Add(fGmtTime)
     256            .End()
     257        .End()
     258        .SetInsets(5, 5, 5, 5);
    276259}
    277260
    278261
  • src/preferences/time/TZDisplay.h

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Andrew McCall <mccall@@digitalparadise.co.uk>
    77 *      Mike Berg <mike@berg-net.us>
    88 *      Julun <host.haiku@gmx.de>
    9  *
     9 *      Hamish Morrison <hamish@lavabit.com>
    1010 */
    1111#ifndef _TZ_DISPLAY_H
    1212#define _TZ_DISPLAY_H
    1313
    1414
     15#include <String.h>
    1516#include <View.h>
    16 #include <String.h>
    1717
    1818
    1919class TTZDisplay : public BView {
    2020public:
    21                                 TTZDisplay(BRect frame, const char* name,
     21                                TTZDisplay(const char* name,
    2222                                    const char* label);
    2323    virtual                     ~TTZDisplay();
    2424
    2525    virtual void                AttachedToWindow();
    2626    virtual void                ResizeToPreferred();
    2727    virtual void                Draw(BRect updateRect);
     28   
     29    virtual BSize               MaxSize();
     30    virtual BSize               MinSize();
     31    virtual BSize               PreferredSize();
    2832
    2933            const char*         Label() const;
    3034            void                SetLabel(const char* label);
     
    3640            void                SetTime(const char* time);
    3741
    3842private:
     43            BSize               _CalcPrefSize();
     44
    3945            BString             fLabel;
    4046            BString             fText;
    4147            BString             fTime;
     
    4349
    4450
    4551#endif  // _TZ_DISPLAY_H
    46 
  • src/preferences/time/Time.cpp

     
    11/*
    2  * Copyright 2002-2007, Haiku. All rights reserved.
     2 * Copyright 2002-2011, Haiku. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Andrew McCall <mccall@digitalparadise.co.uk>
    77 *      Mike Berg <mike@berg-net.us>
    88 *      Julun <host.haiku@gmx.de>
     9 *      Hamish Morrison <hamish@lavabit.com>
    910 */
    1011
    1112#include "Time.h"
    12 #include "TimeWindow.h"
    1313
     14#include <stdio.h>
     15#include <unistd.h>
    1416
    1517#include <Alert.h>
    1618#include <Catalog.h>
    1719
    18 #include <unistd.h>
     20#include "NetworkTimeView.h"
     21#include "TimeWindow.h"
    1922
     23
    2024#undef B_TRANSLATE_CONTEXT
    2125#define B_TRANSLATE_CONTEXT "Time"
    2226
     27
    2328const char* kAppSignature = "application/x-vnd.Haiku-Time";
    2429
    2530
    2631TimeApplication::TimeApplication()
    27     : BApplication(kAppSignature),
    28       fWindow(NULL)
     32    :
     33    BApplication(kAppSignature),
     34    fWindow(NULL)
    2935{
    30     fWindow = new TTimeWindow(BRect(100, 100, 570, 327));
     36    fWindow = new TTimeWindow();
    3137}
    3238
    3339
     
    4753TimeApplication::AboutRequested()
    4854{
    4955    BAlert* alert = new BAlert(B_TRANSLATE("about"),
    50         B_TRANSLATE("Time & Date, writen by:\n\n\tAndrew Edward McCall\n\tMike Berg\n\t"
    51                     "Julun\n\tPhilippe Saint-Pierre\n\nCopyright 2004-2008, Haiku."),
     56        B_TRANSLATE(
     57        "Time & Date, writen by:\n\n\tAndrew Edward McCall\n\tMike Berg\n\t"
     58        "Julun\n\tPhilippe Saint-Pierre\n\nCopyright 2004-2008, Haiku."),
    5259        B_TRANSLATE("OK"));
    5360    alert->Go();
    5461}
    5562
    5663
    57 //  #pragma mark -
    58 
    59 
    6064int
    6165main(int argc, char** argv)
    6266{
    63     TimeApplication app;
    64     setuid(0);
    65     app.Run();
     67    if (argc > 1) {
     68        if (strcmp(argv[1], "--update") != 0)
     69            return 0;
     70       
     71        Settings settings;
     72        if (!settings.GetSynchronizeAtBoot())
     73            return 0;
    6674
     75        const char* errorString = NULL;
     76        int32 errorCode = 0;
     77        if (update_time(settings, &errorString, &errorCode) == B_OK)
     78            printf("Synchronization successful\r\n");
     79        else if (errorCode != 0)
     80            printf("The following error occured "
     81                "while synchronizing:\r\n%s: %s\r\n",
     82                errorString, strerror(errorCode));
     83        else
     84            printf("The following error occured "
     85                "while synchronizing:\r\n%s\r\n",
     86                errorString);
     87    }
     88    else {
     89        TimeApplication app;
     90        setuid(0);
     91        app.Run();
     92    }
     93
    6794    return 0;
    6895}
    69 
  • src/preferences/time/DateTimeEdit.cpp

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    88 *      Julun <host.haiku@gmx.de>
    99 *      Clemens <mail@Clemens-Zeidler.de>
    1010 *      Adrien Destugues <pulkomandy@pulkomandy.cx>
     11 *      Hamish Morrison <hamish@lavabit.com>
    1112 */
    1213
    13 
    1414#include "DateTimeEdit.h"
    1515
    1616#include <stdlib.h>
     
    2424using BPrivate::B_LOCAL_TIME;
    2525
    2626
    27 TTimeEdit::TTimeEdit(BRect frame, const char* name, uint32 sections)
     27TTimeEdit::TTimeEdit(const char* name, uint32 sections)
    2828    :
    29     TSectionEdit(frame, name, sections),
     29    TSectionEdit(name, sections),
    3030    fLastKeyDownTime(0),
    3131    fFields(NULL),
    3232    fFieldCount(0),
     
    5757    int32 section = FocusIndex();
    5858    if (section < 0 || section > 2)
    5959        return;
    60 
    6160    bigtime_t currentTime = system_time();
    6261    if (currentTime - fLastKeyDownTime < 1000000) {
    6362        int32 doubleDigit = number + fLastKeyDownInt * 10;
     
    8483{
    8584    // make sure we call the base class method, as it
    8685    // will create the arrow bitmaps and the section list
    87     TSectionEdit::InitView();
    88 
    8986    fTime = BDateTime::CurrentDateTime(B_LOCAL_TIME);
    9087    _UpdateFields();
    91 
    92     SetSections(fSectionArea);
    9388}
    9489
    9590
    9691void
    97 TTimeEdit::DrawSection(uint32 index, bool hasFocus)
     92TTimeEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus)
    9893{
    99     TSection* section = static_cast<TSection*>(fSectionList->ItemAt(index));
    100     if (!section)
    101         return;
    102 
    10394    if (fFieldPositions == NULL || index * 2 + 1 >= (uint32)fFieldPosCount)
    10495        return;
    105 
    106     BRect bounds = section->Frame();
    107 
    10896    SetLowColor(ViewColor());
    10997    if (hasFocus)
    11098        SetLowColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
     
    113101    fText.CopyCharsInto(field, fFieldPositions[index * 2],
    114102        fFieldPositions[index * 2 + 1] - fFieldPositions[index * 2]);
    115103
    116     // calc and center text in section rect
    117     float width = be_plain_font->StringWidth(field);
    118 
    119     BPoint offset(-((bounds.Width()- width) / 2.0) - 1.0,
    120         bounds.Height() / 2.0 - 6.0);
    121 
     104    BPoint point(bounds.LeftBottom());
     105    point.y -= bounds.Height() / 2.0 - 6.0;
     106    point.x += (bounds.Width() - StringWidth(field)) / 2;
    122107    SetHighColor(0, 0, 0, 255);
    123108    FillRect(bounds, B_SOLID_LOW);
    124     DrawString(field, bounds.LeftBottom() - offset);
     109    DrawString(field, point);
    125110}
    126111
    127112
    128113void
    129 TTimeEdit::DrawSeparator(uint32 index)
     114TTimeEdit::DrawSeparator(uint32 index, BRect bounds)
    130115{
    131     TSection* section = static_cast<TSection*>(fSectionList->ItemAt(index));
    132     if (!section)
    133         return;
    134 
    135116    if (fFieldPositions == NULL || index * 2 + 2 >= (uint32)fFieldPosCount)
    136117        return;
    137118
     
    139120    fText.CopyCharsInto(field, fFieldPositions[index * 2 + 1],
    140121        fFieldPositions[index * 2 + 2] - fFieldPositions[index * 2 + 1]);
    141122
    142     float sepWidth = SeparatorWidth();
    143     BRect bounds = section->Frame();
    144     float width = be_plain_font->StringWidth(field);
    145     BPoint offset(-((sepWidth - width) / 2.0) - 1.0,
    146         bounds.Height() / 2.0 - 6.0);
    147     DrawString(field, bounds.RightBottom() - offset);
     123    BPoint point(bounds.LeftBottom());
     124    point.y -= bounds.Height() / 2.0 - 6.0;
     125    point.x += (bounds.Width() - StringWidth(field)) / 2;
     126    SetHighColor(0, 0, 0, 255);
     127    DrawString(field, point);
    148128}
    149129
    150130
    151 void
    152 TTimeEdit::SetSections(BRect area)
     131float
     132TTimeEdit::SeparatorWidth()
    153133{
    154     // by default divide up the sections evenly
    155     BRect bounds(area);
    156 
    157     float sepWidth = SeparatorWidth();
    158 
    159     float sep_2 = ceil(sepWidth / fSectionCount + 1);
    160     float width = bounds.Width() / fSectionCount - sep_2;
    161     bounds.right = bounds.left + (width - sepWidth / fSectionCount);
    162 
    163     for (uint32 idx = 0; idx < fSectionCount; idx++) {
    164         fSectionList->AddItem(new TSection(bounds));
    165 
    166         bounds.left = bounds.right + sepWidth;
    167         if (idx == fSectionCount - 2)
    168             bounds.right = area.right - 1;
    169         else
    170             bounds.right = bounds.left + (width - sep_2);
    171     }
     134    return 10.0f;
    172135}
    173136
    174137
    175138float
    176 TTimeEdit::SeparatorWidth() const
     139TTimeEdit::MinSectionWidth()
    177140{
    178     return 10.0f;
     141    return be_plain_font->StringWidth("00");
    179142}
    180143
    181144
     
    236199
    237200    // send message to change time
    238201    DispatchMessage();
     202   
    239203}
    240204
    241205
     
    247211
    248212    message->AddBool("time", true);
    249213
    250     for (int32 index = 0; index < fSectionList->CountItems() - 1; ++index) {
     214    for (int32 index = 0; index < (int)fSectionCount; ++index) {
    251215        uint32 data = _SectionValue(index);
    252216
    253217        if (fFocus == index)
     
    277241TTimeEdit::_UpdateFields()
    278242{
    279243    time_t time = fTime.Time_t();
    280 
     244   
    281245    if (fFieldPositions != NULL) {
    282246        free(fFieldPositions);
    283247        fFieldPositions = NULL;
    284248    }
    285     BLocale::Default()->FormatTime(&fText, fFieldPositions, fFieldPosCount,
    286         time, B_MEDIUM_TIME_FORMAT);
     249    BLocale::Default()->FormatTime(&fText, fFieldPositions,
     250        fFieldPosCount, time, B_MEDIUM_TIME_FORMAT);
    287251
    288252    if (fFields != NULL) {
    289253        free(fFields);
     
    415379}
    416380
    417381
     382float
     383TTimeEdit::PreferredHeight()
     384{
     385    font_height fontHeight;
     386    GetFontHeight(&fontHeight);
     387    return ceilf((fontHeight.ascent + fontHeight.descent) * 1.4);
     388}
     389
     390
    418391//  #pragma mark -
    419392
    420393
    421 TDateEdit::TDateEdit(BRect frame, const char* name, uint32 sections)
     394TDateEdit::TDateEdit(const char* name, uint32 sections)
    422395    :
    423     TSectionEdit(frame, name, sections),
     396    TSectionEdit(name, sections),
    424397    fFields(NULL),
    425398    fFieldCount(0),
    426399    fFieldPositions(NULL),
     
    486459{
    487460    // make sure we call the base class method, as it
    488461    // will create the arrow bitmaps and the section list
    489     TSectionEdit::InitView();
    490 
    491462    fDate = BDate::CurrentDate(B_LOCAL_TIME);
    492463    _UpdateFields();
    493 
    494     SetSections(fSectionArea);
    495464}
    496465
    497466
    498467void
    499 TDateEdit::DrawSection(uint32 index, bool hasFocus)
     468TDateEdit::DrawSection(uint32 index, BRect bounds, bool hasFocus)
    500469{
    501     TSection* section = static_cast<TSection*>(fSectionList->ItemAt(index));
    502     if (!section)
    503         return;
    504 
    505470    if (fFieldPositions == NULL || index * 2 + 1 >= (uint32)fFieldPosCount)
    506471        return;
    507472
     
    513478    fText.CopyCharsInto(field, fFieldPositions[index * 2],
    514479        fFieldPositions[index * 2 + 1] - fFieldPositions[index * 2]);
    515480
    516     // calc and center text in section rect
    517     BRect bounds = section->Frame();
    518     float width = StringWidth(field);
    519     BPoint offset(-(bounds.Width() - width) / 2.0 - 1.0,
    520         (bounds.Height() / 2.0 - 6.0));
    521 
     481    BPoint point(bounds.LeftBottom());
     482    point.y -= bounds.Height() / 2.0 - 6.0;
     483    point.x += (bounds.Width() - StringWidth(field)) / 2;
    522484    SetHighColor(0, 0, 0, 255);
    523485    FillRect(bounds, B_SOLID_LOW);
    524     DrawString(field, bounds.LeftBottom() - offset);
     486    DrawString(field, point);
    525487}
    526488
    527489
    528490void
    529 TDateEdit::DrawSeparator(uint32 index)
     491TDateEdit::DrawSeparator(uint32 index, BRect bounds)
    530492{
    531493    if (index >= 2)
    532494        return;
    533495
    534     TSection* section = static_cast<TSection*>(fSectionList->ItemAt(index));
    535     if (!section)
    536         return;
    537 
    538496    if (fFieldPositions == NULL || index * 2 + 2 >= (uint32)fFieldPosCount)
    539497        return;
    540498
     
    542500    fText.CopyCharsInto(field, fFieldPositions[index * 2 + 1],
    543501        fFieldPositions[index * 2 + 2] - fFieldPositions[index * 2 + 1]);
    544502
    545     BRect bounds = section->Frame();
    546     float width = be_plain_font->StringWidth(field);
    547     float sepWidth = SeparatorWidth();
    548     BPoint offset(-((sepWidth - width) / 2.0) - 1.0,
    549         bounds.Height() / 2.0 - 6.0);
    550 
     503    BPoint point(bounds.LeftBottom());
     504    point.y -= bounds.Height() / 2.0 - 6.0;
     505    point.x += (bounds.Width() - StringWidth(field)) / 2;
    551506    SetHighColor(0, 0, 0, 255);
    552     DrawString(field, bounds.RightBottom() - offset);
     507    DrawString(field, point);
    553508}
    554509
    555510
    556511void
    557 TDateEdit::SetSections(BRect area)
     512TDateEdit::SectionFocus(uint32 index)
    558513{
    559     // TODO : we have to be more clever here, as the fields can move and have
    560     // different sizes depending on the locale
    561 
    562     // create sections
    563     for (uint32 idx = 0; idx < fSectionCount; idx++)
    564         fSectionList->AddItem(new TSection(area));
    565 
    566     BRect bounds(area);
    567     float sepWidth = SeparatorWidth();
    568 
    569     TSection* section = static_cast<TSection*>(fSectionList->ItemAt(0));
    570     float width = be_plain_font->StringWidth("0000") + 10;
    571     bounds.left = area.left;
    572     bounds.right = bounds.left + width;
    573     section->SetFrame(bounds);
    574 
    575     section = static_cast<TSection*>(fSectionList->ItemAt(1));
    576     width = be_plain_font->StringWidth("0000") + 10;
    577     bounds.left = bounds.right + sepWidth;
    578     bounds.right = bounds.left + width;
    579     section->SetFrame(bounds);
    580 
    581     section = static_cast<TSection*>(fSectionList->ItemAt(2));
    582     width = be_plain_font->StringWidth("0000") + 10;
    583     bounds.left = bounds.right + sepWidth;
    584     bounds.right = bounds.left + width;
    585     section->SetFrame(bounds);
     514    fLastKeyDownTime = 0;
     515    fFocus = index;
     516    fHoldValue = _SectionValue(index);
     517    Draw(Bounds());
    586518}
    587519
    588520
    589521float
    590 TDateEdit::SeparatorWidth() const
     522TDateEdit::MinSectionWidth()
    591523{
    592     return 10.0f;
     524    return be_plain_font->StringWidth("00");
    593525}
    594526
    595527
    596 void
    597 TDateEdit::SectionFocus(uint32 index)
     528float
     529TDateEdit::SeparatorWidth()
    598530{
    599     fLastKeyDownTime = 0;
    600     fFocus = index;
    601     fHoldValue = _SectionValue(index);
    602     Draw(Bounds());
     531    return 10.0f;
    603532}
    604533
    605534
     
    657586
    658587    message->AddBool("time", false);
    659588
    660     for (int32 index = 0; index < fSectionList->CountItems(); ++index) {
     589    for (int32 index = 0; index < (int)fSectionCount; ++index) {
    661590        uint32 data = _SectionValue(index);
    662591
    663592        if (fFocus == index)
     
    687616TDateEdit::_UpdateFields()
    688617{
    689618    time_t time = BDateTime(fDate, BTime()).Time_t();
    690 
     619   
    691620    if (fFieldPositions != NULL) {
    692621        free(fFieldPositions);
    693622        fFieldPositions = NULL;
    694623    }
    695624    BLocale::Default()->FormatDate(&fText, fFieldPositions, fFieldPosCount,
    696625        time, B_SHORT_DATE_FORMAT);
    697 
     626   
    698627    if (fFields != NULL) {
    699628        free(fFields);
    700629        fFields = NULL;
    701     }
     630    }   
    702631    BLocale::Default()->GetDateFields(fFields, fFieldCount,
    703632        B_SHORT_DATE_FORMAT);
    704633}
     
    817746
    818747    return value;
    819748}
     749
     750
     751float
     752TDateEdit::PreferredHeight()
     753{
     754    font_height fontHeight;
     755    GetFontHeight(&fontHeight);
     756    return ceilf((fontHeight.ascent + fontHeight.descent) * 1.4);
     757}
  • src/preferences/time/ntp.h

     
     1/*
     2 * Copyright 2004, pinc Software. All Rights Reserved.
     3 * Distributed under the terms of the MIT license.
     4 */
     5#ifndef NTP_H
     6#define NTP_H
     7
     8
     9#include <SupportDefs.h>
     10
     11
     12extern status_t ntp_update_time(const char *host,
     13    const char** errorString, int32* errorCode);
     14
     15
     16#endif  /* NTP_H */
  • src/preferences/time/NetworkTimeView.h

     
     1/*
     2 * Copyright 2011, Haiku, Inc. All Rights Reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Hamish Morrison <hamish@lavabit.com>
     7 *      Axel Dörfler <axeld@pinc-software.de>
     8 */
     9#ifndef NETWORK_TIME_VIEW_H
     10#define NETWORK_TIME_VIEW_H
     11
     12
     13#include <LayoutBuilder.h>
     14
     15
     16class BButton;
     17class BCheckBox;
     18class BListView;
     19class BTextControl;
     20class BMessage;
     21class BMessenger;
     22class BPath;
     23class Settings;
     24
     25
     26static const uint32 kMsgNetworkTimeSettings = 'ntst';
     27static const uint32 kMsgSetDefaultServer = 'setd';
     28static const uint32 kMsgAddServer = 'asrv';
     29static const uint32 kMsgRemoveServer = 'rsrv';
     30static const uint32 kMsgResetServerList = 'rstl';
     31static const uint32 kMsgTryAllServers = 'tras';
     32static const uint32 kMsgSynchronizeAtBoot = 'synb';
     33static const uint32 kMsgSynchronize = 'sync';
     34static const uint32 kMsgStopSynchronization = 'stps';
     35static const uint32 kMsgSynchronizationResult = 'syrs';
     36static const uint32 kMsgNetworkTimeChange = 'ntch';
     37
     38
     39status_t
     40update_time(const Settings& settings, BMessenger* messenger,
     41    thread_id* thread);
     42
     43
     44status_t
     45update_time(const Settings& settings, const char** errorString,
     46    int32* errorCode);
     47
     48
     49class Settings {
     50public:
     51                            Settings();
     52                            ~Settings();
     53
     54            void            AddServer(const char* server);
     55            const char*     GetServer(int32 index) const;
     56            void            RemoveServer(const char* server);
     57            void            SetDefaultServer(int32 index);
     58            int32           GetDefaultServer() const;
     59            void            SetTryAllServers(bool boolean);
     60            bool            GetTryAllServers() const;
     61            void            SetSynchronizeAtBoot(bool boolean);
     62            bool            GetSynchronizeAtBoot() const;
     63
     64            void            ResetServersToDefaults();
     65            void            ResetToDefaults();
     66            void            Revert();
     67            bool            SettingsChanged();
     68           
     69            status_t        Load();
     70            status_t        Save();
     71
     72private:
     73            int32           _GetStringByValue(const char* name,
     74                                const char* value);
     75            status_t        _GetPath(BPath& path);
     76
     77            BMessage        fMessage;
     78            BMessage        fOldMessage;
     79            bool            fWasUpdated;
     80};
     81
     82
     83class NetworkTimeView : public BGroupView {
     84public:
     85                            NetworkTimeView(const char* name);
     86       
     87    virtual void            MessageReceived(BMessage* message);
     88    virtual void            AttachedToWindow();
     89   
     90            bool            CheckCanRevert();
     91private:
     92            void            _InitView();
     93            void            _UpdateServerList();
     94            void            _DoneSynchronizing();
     95
     96            Settings        fSettings;
     97
     98            BTextControl*   fServerTextControl;
     99            BButton*        fAddButton;
     100            BButton*        fRemoveButton;
     101            BButton*        fResetButton;
     102
     103            BListView*      fServerListView;
     104            BCheckBox*      fTryAllServersCheckBox;
     105            BCheckBox*      fSynchronizeAtBootCheckBox;
     106            BButton*        fSynchronizeButton;
     107
     108            thread_id       fUpdateThread;
     109};
     110   
     111#endif
  • src/preferences/time/TimeZoneListItem.h

     
    55 * Authors:
    66 *      Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
    77 */
    8 
    98#ifndef _TIME_ZONE_LIST_ITEM_H
    109#define _TIME_ZONE_LIST_ITEM_H
    1110
  • src/preferences/time/BaseView.h

     
    1010#define _BASE_VIEW_H
    1111
    1212
     13#include <LayoutBuilder.h>
    1314#include <Message.h>
    14 #include <View.h>
    1515
    1616
    17 class TTimeBaseView: public BView {
     17class TTimeBaseView : public BGroupView {
    1818public:
    19                                 TTimeBaseView(BRect frame, const char* name);
     19                                TTimeBaseView(const char* name);
    2020    virtual                     ~TTimeBaseView();
    2121
    2222    virtual void                Pulse();
     
    2626
    2727private:
    2828            void                _SendNotices();
    29 
    30 private:
     29           
    3130            BMessage            fMessage;
    3231};
    3332
  • src/preferences/time/ZoneView.h

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Mike Berg <mike@berg-net.us>
    77 *      Julun <host.haiku@gmx.de>
     8 *      Hamish Morrison <hamish@lavabit.com>
    89 */
    910#ifndef ZONE_VIEW_H
    1011#define ZONE_VIEW_H
    1112
    1213
     14#include <LayoutBuilder.h>
    1315#include <TimeZone.h>
    14 #include <View.h>
    1516
    1617
    1718class BButton;
     
    2425class TTZDisplay;
    2526
    2627
    27 class TimeZoneView : public BView {
     28class TimeZoneView : public BGroupView {
    2829public:
    29                                 TimeZoneView(BRect frame);
     30                                TimeZoneView(const char* name);
    3031    virtual                     ~TimeZoneView();
    3132
    3233    virtual void                AttachedToWindow();
     
    5152
    5253            void                _Revert();
    5354
    54 private:
    5555            BOutlineListView*   fZoneList;
    5656            BButton*            fSetZone;
    5757            TTZDisplay*         fCurrent;
  • src/preferences/time/AnalogClock.cpp

     
    11/*
    2  * Copyright 2004-2009, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    77 *      Julun <host.haiku@gmx.de>
    88 *      Stephan Aßmus <superstippi@gmx.de>
    99 *      Clemens <mail@Clemens-Zeidler.de>
     10 *      Hamish Morrison <hamish@lavabit.com>
    1011 */
    1112
    1213#include "AnalogClock.h"
     
    1415#include <math.h>
    1516#include <stdio.h>
    1617
    17 #include <Bitmap.h>
     18#include <LayoutUtils.h>
    1819#include <Message.h>
    1920#include <Window.h>
    2021
     
    2425#define DRAG_DELTA_PHI 0.2
    2526
    2627
    27 class OffscreenClock : public BView {
    28 public:
    29                             OffscreenClock(BRect frame, const char* name,
    30                                 bool drawSecondHand = true);
    31     virtual                 ~OffscreenClock();
     28TAnalogClock::TAnalogClock(const char* name,
     29    bool drawSecondHand, bool interactive)
     30    :
     31    BView(name, B_WILL_DRAW | B_DRAW_ON_CHILDREN | B_FRAME_EVENTS),
     32    fHours(0),
     33    fMinutes(0),
     34    fSeconds(0),
     35    fDirty(true),
     36    fHourDragging(false),
     37    fMinuteDragging(false),
     38    fDrawSecondHand(drawSecondHand),
     39    fInteractive(interactive),
     40    fTimeChangeIsOngoing(false)
     41{
     42    SetFlags(Flags() | B_SUBPIXEL_PRECISE);
     43}
    3244
    33             void            SetTime(int32 hour, int32 minute, int32 second);
    34             void            GetTime(int32* hour, int32* minute, int32* second);
    35             bool            IsDirty() const {   return fDirty;  }
    36             void            DrawClock();
    3745
    38             bool            InHourHand(BPoint point);
    39             bool            InMinuteHand(BPoint point);
     46TAnalogClock::~TAnalogClock()
     47{
     48}
    4049
    41             void            SetHourHand(BPoint point);
    42             void            SetMinuteHand(BPoint point);
    4350
    44             void            SetHourDragging(bool dragging);
    45             void            SetMinuteDragging(bool dragging);
     51void
     52TAnalogClock::MessageReceived(BMessage* message)
     53{
     54    int32 change;
     55    switch (message->what) {
     56        case B_OBSERVER_NOTICE_CHANGE:
     57            message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change);
     58            switch (change) {
     59                case H_TM_CHANGED:
     60                {
     61                    int32 hour = 0;
     62                    int32 minute = 0;
     63                    int32 second = 0;
     64                    if (message->FindInt32("hour", &hour) == B_OK
     65                     && message->FindInt32("minute", &minute) == B_OK
     66                     && message->FindInt32("second", &second) == B_OK)
     67                        SetTime(hour, minute, second);
     68                    break;
     69                }
     70                default:
     71                    BView::MessageReceived(message);
     72                    break;
     73            }
     74        break;
     75        default:
     76            BView::MessageReceived(message);
     77            break;
     78    }
     79}
    4680
    47 private:
    48             float           _GetPhi(BPoint point);
    49             bool            _InHand(BPoint point, int32 ticks, float radius);
    50             void            _DrawHands(float x, float y, float radius,
    51                                 rgb_color hourHourColor,
    52                                 rgb_color hourMinuteColor,
    53                                 rgb_color secondsColor, rgb_color knobColor);
    5481
    55             int32           fHours;
    56             int32           fMinutes;
    57             int32           fSeconds;
    58             bool            fDirty;
     82void
     83TAnalogClock::MouseDown(BPoint point)
     84{
     85    if(!fInteractive) {
     86        BView::MouseDown(point);
     87        return;
     88    }
     89   
     90    if (InMinuteHand(point)) {
     91        fMinuteDragging = true;
     92        fDirty = true;
     93        SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
     94        Invalidate();
     95        return;
     96    }
     97    if (InHourHand(point)) {
     98        fHourDragging = true;
     99        fDirty = true;
     100        SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
     101        Invalidate();
     102        return;
     103    }
     104}
    59105
    60             float           fCenterX;
    61             float           fCenterY;
    62             float           fRadius;
    63106
    64             bool            fHourDragging;
    65             bool            fMinuteDragging;
    66            
    67             bool            fDrawSecondHand;
    68 };
     107void
     108TAnalogClock::MouseUp(BPoint point)
     109{
     110    if(!fInteractive) {
     111        BView::MouseUp(point);
     112        return;
     113    }
     114   
     115    if (fHourDragging || fMinuteDragging) {
     116        int32 hour, minute, second;
     117        GetTime(&hour, &minute, &second);
     118        BMessage message(H_USER_CHANGE);
     119        message.AddBool("time", true);
     120        message.AddInt32("hour", hour);
     121        message.AddInt32("minute", minute);
     122        Window()->PostMessage(&message);
     123        fTimeChangeIsOngoing = true;
     124    }
     125    fHourDragging = false;
     126    fDirty = true;
     127    fMinuteDragging = false;
     128    fDirty = true;
     129}
    69130
    70131
    71 OffscreenClock::OffscreenClock(BRect frame, const char* name,
    72     bool drawSecondHand)
    73     :
    74     BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW),
    75     fHours(0),
    76     fMinutes(0),
    77     fSeconds(0),
    78     fDirty(true),
    79     fHourDragging(false),
    80     fMinuteDragging(false),
    81     fDrawSecondHand(drawSecondHand)
     132void
     133TAnalogClock::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
    82134{
    83     SetFlags(Flags() | B_SUBPIXEL_PRECISE);
     135    if(!fInteractive) {
     136        BView::MouseMoved(point, transit, message);
     137        return;
     138    }
    84139
    85     BRect bounds = Bounds();
    86     fCenterX = floorf((bounds.left + bounds.right) / 2 + 0.5) + 0.5;
    87     fCenterY = floorf((bounds.top + bounds.bottom) / 2 + 0.5) + 0.5;
    88         // + 0.5 is for the offset to pixel centers
    89         // (important when drawing with B_SUBPIXEL_PRECISE)
     140    if (fMinuteDragging)
     141        SetMinuteHand(point);
     142    if (fHourDragging)
     143        SetHourHand(point);
    90144
    91     fRadius = floorf((MIN(bounds.Width(), bounds.Height()) / 2.0)) - 2.5;
    92     fRadius -= 3;
     145    Invalidate();
    93146}
    94147
    95148
    96 OffscreenClock::~OffscreenClock()
     149void
     150TAnalogClock::Draw(BRect /*updateRect*/)
    97151{
     152    if (fDirty)
     153        DrawClock();
    98154}
    99155
    100156
    101157void
    102 OffscreenClock::SetTime(int32 hour, int32 minute, int32 second)
     158TAnalogClock::SetTime(int32 hour, int32 minute, int32 second)
    103159{
     160    // don't set the time if the hands are in a drag action
     161    if (fHourDragging || fMinuteDragging || fTimeChangeIsOngoing)
     162        return;
     163   
    104164    if (fHours == hour && fMinutes == minute && fSeconds == second)
    105165        return;
    106166
     
    109169    fSeconds = second;
    110170
    111171    fDirty = true;
     172
     173    BWindow* window = Window();
     174    if (window && window->Lock()) {
     175        Invalidate();
     176        Window()->Unlock();
     177    }
    112178}
    113179
    114180
     181bool
     182TAnalogClock::IsChangingTime()
     183{
     184    return fTimeChangeIsOngoing;
     185}
     186
     187
    115188void
    116 OffscreenClock::GetTime(int32* hour, int32* minute, int32* second)
     189TAnalogClock::ChangeTimeFinished()
    117190{
     191    fTimeChangeIsOngoing = false;
     192}
     193
     194
     195void
     196TAnalogClock::GetTime(int32* hour, int32* minute, int32* second)
     197{
    118198    *hour = fHours;
    119199    *minute = fMinutes;
    120200    *second = fSeconds;
     
    122202
    123203
    124204void
    125 OffscreenClock::DrawClock()
     205TAnalogClock::DrawClock()
    126206{
    127207    if (!LockLooper())
    128208        return;
     
    132212    rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
    133213    SetHighColor(background);
    134214    FillRect(bounds);
    135 
    136 
     215   
    137216    bounds.Set(fCenterX - fRadius, fCenterY - fRadius,
    138217        fCenterX + fRadius, fCenterY + fRadius);
    139218
     
    207286}
    208287
    209288
     289void
     290TAnalogClock::FrameResized(float, float)
     291{
     292    BRect bounds = Bounds();
     293
     294    // + 0.5 is for the offset to pixel centers
     295    // (important when drawing with B_SUBPIXEL_PRECISE)
     296    fCenterX = floorf((bounds.left + bounds.right) / 2 + 0.5) + 0.5;
     297    fCenterY = floorf((bounds.top + bounds.bottom) / 2 + 0.5) + 0.5;
     298    fRadius = floorf((MIN(bounds.Width(), bounds.Height()) / 2.0)) - 2.5;
     299    fRadius -= 3;
     300}
     301
     302
     303BSize
     304TAnalogClock::MaxSize()
     305{
     306    return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
     307        BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
     308}
     309
     310
     311BSize
     312TAnalogClock::MinSize()
     313{
     314    return BSize(0, 0);
     315}
     316
     317
     318BSize
     319TAnalogClock::PreferredSize()
     320{
     321    return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
     322        BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
     323}
     324
     325
    210326bool
    211 OffscreenClock::InHourHand(BPoint point)
     327TAnalogClock::InHourHand(BPoint point)
    212328{
    213329    int32 ticks = fHours;
    214330    if (ticks > 12)
     
    222338
    223339
    224340bool
    225 OffscreenClock::InMinuteHand(BPoint point)
     341TAnalogClock::InMinuteHand(BPoint point)
    226342{
    227343    return _InHand(point, fMinutes, fRadius * 0.9);
    228344}
    229345
    230346
    231347void
    232 OffscreenClock::SetHourHand(BPoint point)
     348TAnalogClock::SetHourHand(BPoint point)
    233349{
    234350    point.x -= fCenterX;
    235351    point.y -= fCenterY;
     
    247363
    248364
    249365void
    250 OffscreenClock::SetMinuteHand(BPoint point)
     366TAnalogClock::SetMinuteHand(BPoint point)
    251367{
    252368    point.x -= fCenterX;
    253369    point.y -= fCenterY;
     
    260376}
    261377
    262378
    263 void
    264 OffscreenClock::SetHourDragging(bool dragging)
    265 {
    266     fHourDragging = dragging;
    267     fDirty = true;
    268 }
    269 
    270 
    271 void
    272 OffscreenClock::SetMinuteDragging(bool dragging)
    273 {
    274     fMinuteDragging = dragging;
    275     fDirty = true;
    276 }
    277 
    278 
    279379float
    280 OffscreenClock::_GetPhi(BPoint point)
     380TAnalogClock::_GetPhi(BPoint point)
    281381{
    282382    if (point.x == 0 && point.y < 0)
    283383        return 2 * M_PI;
     
    302402
    303403
    304404bool
    305 OffscreenClock::_InHand(BPoint point, int32 ticks, float radius)
     405TAnalogClock::_InHand(BPoint point, int32 ticks, float radius)
    306406{
    307407    point.x -= fCenterX;
    308408    point.y -= fCenterY;
     
    323423
    324424
    325425void
    326 OffscreenClock::_DrawHands(float x, float y, float radius,
    327     rgb_color hourColor,
    328     rgb_color minuteColor,
    329     rgb_color secondsColor,
    330     rgb_color knobColor)
     426TAnalogClock::_DrawHands(float x, float y, float radius,
     427    rgb_color hourColor, rgb_color minuteColor,
     428    rgb_color secondsColor, rgb_color knobColor)
    331429{
    332430    float offsetX;
    333431    float offsetY;
     
    361459    SetHighColor(knobColor);
    362460    FillEllipse(BPoint(x, y), radius * 0.06, radius * 0.06);
    363461}
    364 
    365 
    366 //  #pragma mark -
    367 
    368 
    369 TAnalogClock::TAnalogClock(BRect frame, const char* name,
    370     bool drawSecondHand, bool interactive)
    371     :
    372     BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_DRAW_ON_CHILDREN),
    373     fBitmap(NULL),
    374     fClock(NULL),
    375     fDrawSecondHand(drawSecondHand),
    376     fInteractive(interactive),
    377     fDraggingHourHand(false),
    378     fDraggingMinuteHand(false),
    379     fTimeChangeIsOngoing(false)
    380 {
    381     _InitView(frame);
    382 }
    383 
    384 
    385 TAnalogClock::~TAnalogClock()
    386 {
    387     delete fBitmap;
    388 }
    389 
    390 
    391 void
    392 TAnalogClock::_InitView(BRect rect)
    393 {
    394     fClock = new OffscreenClock(Bounds(), "offscreen", fDrawSecondHand);
    395     fBitmap = new BBitmap(Bounds(), B_RGB32, true);
    396     fBitmap->Lock();
    397     fBitmap->AddChild(fClock);
    398     fBitmap->Unlock();
    399 }
    400 
    401 
    402 void
    403 TAnalogClock::AttachedToWindow()
    404 {
    405     SetViewColor(B_TRANSPARENT_COLOR);
    406 }
    407 
    408 
    409 void
    410 TAnalogClock::MessageReceived(BMessage* message)
    411 {
    412     int32 change;
    413     switch (message->what) {
    414         case B_OBSERVER_NOTICE_CHANGE:
    415             message->FindInt32(B_OBSERVE_WHAT_CHANGE, &change);
    416             switch (change) {
    417                 case H_TM_CHANGED:
    418                 {
    419                     int32 hour = 0;
    420                     int32 minute = 0;
    421                     int32 second = 0;
    422                     if (message->FindInt32("hour", &hour) == B_OK
    423                      && message->FindInt32("minute", &minute) == B_OK
    424                      && message->FindInt32("second", &second) == B_OK)
    425                         SetTime(hour, minute, second);
    426                     break;
    427                 }
    428                 default:
    429                     BView::MessageReceived(message);
    430                     break;
    431             }
    432         break;
    433         default:
    434             BView::MessageReceived(message);
    435             break;
    436     }
    437 }
    438 
    439 
    440 void
    441 TAnalogClock::MouseDown(BPoint point)
    442 {
    443     if(!fInteractive) {
    444         BView::MouseDown(point);
    445         return;
    446     }
    447    
    448     fDraggingMinuteHand = fClock->InMinuteHand(point);
    449     if (fDraggingMinuteHand) {
    450         fClock->SetMinuteDragging(true);
    451         SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
    452         Invalidate();
    453         return;
    454     }
    455     fDraggingHourHand = fClock->InHourHand(point);
    456     if (fDraggingHourHand) {
    457         fClock->SetHourDragging(true);
    458         SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
    459         Invalidate();
    460         return;
    461     }
    462 }
    463 
    464 
    465 void
    466 TAnalogClock::MouseUp(BPoint point)
    467 {
    468     if(!fInteractive) {
    469         BView::MouseUp(point);
    470         return;
    471     }
    472    
    473     if (fDraggingHourHand || fDraggingMinuteHand) {
    474         int32 hour, minute, second;
    475         fClock->GetTime(&hour, &minute, &second);
    476         BMessage message(H_USER_CHANGE);
    477         message.AddBool("time", true);
    478         message.AddInt32("hour", hour);
    479         message.AddInt32("minute", minute);
    480         Window()->PostMessage(&message);
    481         fTimeChangeIsOngoing = true;
    482     }
    483     fDraggingHourHand = false;
    484     fDraggingMinuteHand = false;
    485     fClock->SetMinuteDragging(false);
    486     fClock->SetHourDragging(false);
    487 }
    488 
    489 
    490 void
    491 TAnalogClock::MouseMoved(BPoint point, uint32 transit, const BMessage* message)
    492 {
    493     if(!fInteractive) {
    494         BView::MouseMoved(point, transit, message);
    495         return;
    496     }
    497 
    498     if (fDraggingMinuteHand)
    499         fClock->SetMinuteHand(point);
    500     if (fDraggingHourHand)
    501         fClock->SetHourHand(point);
    502 
    503     Invalidate();
    504 }
    505 
    506 
    507 void
    508 TAnalogClock::Draw(BRect /*updateRect*/)
    509 {
    510     if (fBitmap) {
    511         if (fClock->IsDirty())
    512             fClock->DrawClock();
    513         DrawBitmap(fBitmap, BPoint(0, 0));
    514     }
    515 }
    516 
    517 
    518 void
    519 TAnalogClock::SetTime(int32 hour, int32 minute, int32 second)
    520 {
    521     // don't set the time if the hands are in a drag action
    522     if (fDraggingHourHand || fDraggingMinuteHand || fTimeChangeIsOngoing)
    523         return;
    524 
    525     if (fClock)
    526         fClock->SetTime(hour, minute, second);
    527 
    528     BWindow* window = Window();
    529     if (window && window->Lock()) {
    530         Invalidate();
    531         Window()->Unlock();
    532     }
    533 }
    534 
    535 
    536 void
    537 TAnalogClock::ChangeTimeFinished()
    538 {
    539     fTimeChangeIsOngoing = false;
    540 }
  • src/preferences/time/SectionEdit.h

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Mike Berg <mike@berg-net.us>
    77 *      Julun <host.haiku@gmx.de>
    8  *
     8 *      Hamish Morrison <hamish@lavabit.com>
    99 */
    1010#ifndef _SECTION_EDIT_H
    1111#define _SECTION_EDIT_H
     
    1818class BList;
    1919
    2020
    21 class TSection {
     21class TSectionEdit : public BControl {
    2222public:
    23                                 TSection(BRect frame);
    24 
    25             BRect               Bounds() const;
    26             void                SetFrame(BRect frame);
    27             BRect               Frame() const;
    28 
    29 private:
    30             BRect               fFrame;
    31 };
    32 
    33 
    34 class TSectionEdit: public BControl {
    35 public:
    36                                 TSectionEdit(BRect frame, const char* name,
     23                                TSectionEdit(const char* name,
    3724                                    uint32 sections);
    3825    virtual                     ~TSectionEdit();
    3926
     
    4330    virtual void                MakeFocus(bool focused = true);
    4431    virtual void                KeyDown(const char* bytes, int32 numBytes);
    4532
     33            BSize               MaxSize();
     34            BSize               MinSize();
     35            BSize               PreferredSize();
     36
    4637            uint32              CountSections() const;
    4738            int32               FocusIndex() const;
    4839            BRect               SectionArea() const;
    4940
    5041protected:
    51     virtual void                InitView();
    52 
    53     // hooks
    5442    virtual void                DrawBorder(const BRect& updateRect);
    55     virtual void                DrawSection(uint32 index, bool isFocus) {}
    56     virtual void                DrawSeparator(uint32 index) {}
     43    virtual void                DrawSection(uint32 index, BRect bounds,
     44                                    bool isFocus) {}
     45    virtual void                DrawSeparator(uint32 index, BRect bounds) {}
    5746
     47            BRect               FrameForSection(uint32 index);
     48            BRect               FrameForSeparator(uint32 index);
     49
    5850    virtual void                SectionFocus(uint32 index) {}
    5951    virtual void                SectionChange(uint32 index, uint32 value) {}
    6052    virtual void                SetSections(BRect area) {}
    61     virtual float               SeparatorWidth() const;
    62 
     53   
     54    virtual float               SeparatorWidth() = 0;
     55    virtual float               MinSectionWidth() = 0;
     56    virtual float               PreferredHeight() = 0;
     57   
    6358    virtual void                DoUpPress() {}
    6459    virtual void                DoDownPress() {}
    6560
    6661    virtual void                DispatchMessage();
    6762    virtual void                BuildDispatch(BMessage* message) = 0;
    68 
    69 protected:
    70             BList*              fSectionList;
    71 
     63           
    7264            BRect               fUpRect;
    7365            BRect               fDownRect;
    74             BRect               fSectionArea;
    7566
    7667            int32               fFocus;
    7768            uint32              fSectionCount;
  • src/preferences/time/TZDisplay.cpp

     
    11/*
    2  * Copyright 2004-2007, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    66 *      Andrew McCall <mccall@@digitalparadise.co.uk>
    77 *      Mike Berg <mike@berg-net.us>
    88 *      Julun <host.haiku@gmx.de>
    9  *
     9 *      Hamish Morrison <hamish@lavabit.com>
    1010 */
    1111
     12#include "TZDisplay.h"
     13
    1214#include <stdio.h>
    1315
    14 #include "TZDisplay.h"
     16#include <LayoutUtils.h>
    1517
    1618
    17 namespace {
    18     float _FontHeight()
    19     {
    20         font_height fontHeight;
    21         be_plain_font->GetHeight(&fontHeight);
    22         float height = ceil(fontHeight.descent + fontHeight.ascent
    23             + fontHeight.leading);
    24         return height;
    25     }
    26 }
    2719
    28 
    29 TTZDisplay::TTZDisplay(BRect frame, const char* name, const char* label)
    30     : BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW),
    31       fLabel(label),
    32       fText(""),
    33       fTime("")
     20TTZDisplay::TTZDisplay(const char* name, const char* label)
     21    :
     22    BView(name, B_WILL_DRAW),
     23    fLabel(label),
     24    fText(""),
     25    fTime("")
    3426{
    3527}
    3628
     
    5143void
    5244TTZDisplay::ResizeToPreferred()
    5345{
    54     ResizeTo(Bounds().Width(), _FontHeight() * 2.0 + 4.0);
     46    BSize size = _CalcPrefSize();
     47    ResizeTo(size.width, size.height);
    5548}
    5649
    5750
    5851void
    59 TTZDisplay::Draw(BRect /* updateRect */)
     52TTZDisplay::Draw(BRect)
    6053{
    6154    SetLowColor(ViewColor());
    6255
    6356    BRect bounds = Bounds();
    6457    FillRect(Bounds(), B_SOLID_LOW);
     58   
     59    font_height height;
     60    GetFontHeight(&height);
     61    float fontHeight = ceilf(height.descent + height.ascent +
     62        height.leading);
    6563
    66     float fontHeight = _FontHeight();
    67 
    68     BPoint pt(bounds.left + 2.0, fontHeight / 2.0 + 2.0);
     64    BPoint pt(bounds.left, ceilf(bounds.top + height.ascent));
    6965    DrawString(fLabel.String(), pt);
    7066
    7167    pt.y += fontHeight;
    7268    DrawString(fText.String(), pt);
    7369
    7470    pt.y -= fontHeight;
    75     pt.x = bounds.right - StringWidth(fTime.String()) - 2.0;
     71    pt.x = bounds.right - StringWidth(fTime.String());
    7672    DrawString(fTime.String(), pt);
    7773}
    7874
     
    8985{
    9086    fLabel.SetTo(label);
    9187    Invalidate();
     88    InvalidateLayout();
    9289}
    9390
    9491
     
    104101{
    105102    fText.SetTo(text);
    106103    Invalidate();
     104    InvalidateLayout();
    107105}
    108106
    109107
     
    119117{
    120118    fTime.SetTo(time);
    121119    Invalidate();
     120    InvalidateLayout();
    122121}
    123122
     123
     124BSize
     125TTZDisplay::MaxSize()
     126{
     127    BSize size = _CalcPrefSize();
     128    size.width = B_SIZE_UNLIMITED;
     129   
     130    return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
     131        size);
     132}
     133
     134
     135BSize
     136TTZDisplay::MinSize()
     137{
     138    return BLayoutUtils::ComposeSize(ExplicitMinSize(),
     139        _CalcPrefSize());
     140}
     141
     142
     143BSize
     144TTZDisplay::PreferredSize()
     145{
     146    return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
     147        _CalcPrefSize());
     148}
     149
     150
     151BSize
     152TTZDisplay::_CalcPrefSize()
     153{
     154    font_height fontHeight;
     155    GetFontHeight(&fontHeight);
     156   
     157    BSize size;
     158    size.height = 2 * ceilf(fontHeight.ascent + fontHeight.descent +
     159        fontHeight.leading);
     160   
     161    float firstLine = ceilf(StringWidth(fLabel.String()) +
     162        StringWidth(" ") + StringWidth(fTime.String()));
     163    float secondLine = ceilf(StringWidth(fText.String()));
     164    size.width = firstLine > secondLine ? firstLine : secondLine;
     165    return size;
     166}
  • src/preferences/time/TimeSettings.h

     
    2929
    3030
    3131#endif  // _TIME_SETTINGS_H
    32 
  • src/preferences/time/TimeWindow.h

     
    55 * Authors:
    66 *      Andrew McCall <mccall@@digitalparadise.co.uk>
    77 *      Julun <host.haiku@gmx.de>
    8  *
    98 */
    109#ifndef _TIME_WINDOW_H
    1110#define _TIME_WINDOW_H
     
    1817class DateTimeView;
    1918class TTimeBaseView;
    2019class TimeZoneView;
     20class NetworkTimeView;
    2121
    2222
    2323class TTimeWindow : public BWindow {
    2424public:
    25                                 TTimeWindow(BRect rect);
     25                                TTimeWindow();
    2626    virtual                     ~TTimeWindow();
    2727
    2828    virtual bool                QuitRequested();
    2929    virtual void                MessageReceived(BMessage* message);
    30             void                SetRevertStatus();
    3130
    3231private:
    3332            void                _InitWindow();
    3433            void                _AlignWindow();
    35 
    3634            void                _SendTimeChangeFinished();
     35            void                _SetRevertStatus();
    3736
    38 private:
    3937            TTimeBaseView*      fBaseView;
    4038            DateTimeView*       fDateTimeView;
    4139            TimeZoneView*       fTimeZoneView;
     40            NetworkTimeView*    fNetworkTimeView;
    4241            BButton*            fRevertButton;
    4342};
    4443
    4544
    4645#endif  // _TIME_WINDOW_H
    47 
  • src/preferences/time/TimeMessages.h

     
    4343// clicked on revert button
    4444const uint32 kMsgRevert = 'rvrt';
    4545
     46// something was changed
     47const uint32 kMsgChange = 'chng';
     48
    4649// change time finished
    4750const uint32 kChangeTimeFinished = 'tcfi';
    4851
    4952
    5053#endif  // _TIME_MESSAGES_H
    51 
  • src/preferences/time/DateTimeView.h

     
    11/*
    2  * Copyright 2004-2010, Haiku, Inc. All Rights Reserved.
     2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
     
    77 *      Mike Berg <mike@berg-net.us>
    88 *      Julun <host.haiku@gmx.de>
    99 *      Philippe Saint-Pierre <stpere@gmail.com>
     10 *      Hamish Morrison <hamish@lavabit.com>
    1011 */
    1112#ifndef _DATE_TIME_VIEW_H
    1213#define _DATE_TIME_VIEW_H
    1314
    1415
    15 #include <View.h>
     16#include <LayoutBuilder.h>
    1617
    1718
    1819class TDateEdit;
     
    2728using BPrivate::BCalendarView;
    2829
    2930
    30 class DateTimeView : public BView {
     31class DateTimeView : public BGroupView {
    3132public:
    32                                 DateTimeView(BRect frame);
     33                                DateTimeView(const char* name);
    3334    virtual                     ~DateTimeView();
    3435
    3536    virtual void                AttachedToWindow();
     
    4849            void                _Revert();
    4950            time_t              _PrefletUptime() const;
    5051
    51 private:
    5252            BRadioButton*       fLocalTime;
    5353            BRadioButton*       fGmtTime;
    5454            TDateEdit*          fDateEdit;
  • src/kits/shared/CalendarView.cpp

     
    1111
    1212#include <stdlib.h>
    1313
     14#include <LayoutUtils.h>
    1415#include <Window.h>
    1516
    1617
     
    7273}
    7374
    7475
     76BCalendarView::BCalendarView(const char* name, uint32 flags)
     77    :
     78    BView(name, flags),
     79    BInvoker(),
     80    fSelectionMessage(NULL),
     81    fDay(0),
     82    fYear(0),
     83    fMonth(0),
     84    fFocusChanged(false),
     85    fSelectionChanged(false),
     86    fWeekStart(B_WEEK_START_SUNDAY),
     87    fDayNameHeaderVisible(true),
     88    fWeekNumberHeaderVisible(true)
     89{
     90    _InitObject();
     91}
     92
     93
    7594BCalendarView::~BCalendarView()
    7695{
    7796    SetSelectionMessage(NULL);
     
    559578}
    560579
    561580
     581BSize
     582BCalendarView::MaxSize()
     583{
     584    return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
     585        BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
     586}
     587
     588
     589BSize
     590BCalendarView::MinSize()
     591{
     592    float width, height;
     593    _GetPreferredSize(&width, &height);
     594    return BLayoutUtils::ComposeSize(ExplicitMinSize(),
     595        BSize(width, height));
     596}
     597
     598
     599BSize
     600BCalendarView::PreferredSize()
     601{
     602    return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
     603        MinSize());
     604}
     605
     606
    562607int32
    563608BCalendarView::Day() const
    564609{
  • headers/private/shared/CalendarView.h

     
    3636                                BCalendarView(BRect frame, const char *name, week_start start,
    3737                                    uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
    3838                                    uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE);
     39                               
     40                                BCalendarView(const char* name,
     41                                    uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE);
    3942
    4043        virtual                 ~BCalendarView();
    4144
     
    8891
    8992        virtual void            ResizeToPreferred();
    9093        virtual void            GetPreferredSize(float *width, float *height);
     94       
     95        virtual BSize           MaxSize();
     96        virtual BSize           MinSize();
     97        virtual BSize           PreferredSize();
    9198
    9299        int32                   Day() const;
    93100        int32                   Year() const;