<commit_before>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <fstream>

#include "SuMo.h"
#include "Timer.h"

using namespace std;
/* subtract pedestal values on-line */
static bool PED_SUBTRCT = false;

static int LIMIT_READOUT_RATE = 6000;  //usecs limit between event polling
static int NUM_SEQ_TIMEOUTS = 100;    // number of sequential timeouts before ending run
const float MAX_INT_TIMER = 800.;    // max cpu timer before ending run (secs)
/* note: usb timeout defined in include/stdUSB.h */

bool overwriteExistingFile = false;

int SuMo::log_data(unsigned int NUM_READS, int trig_mode, int acq_rate, const char *log_filename) {
    int check_event;
    int asic_baseline[psecSampleCells];
    int count = 0;
    int psec_cnt = 0;
    int last_k;
    float _now_, t = 0.;
    Timer timer = Timer();
    time_t now;
    unsigned short sample;
    int *Meta;

    char logDataFilename[300];
    char logMetaFilename[300];
    char logPedFilename[300];
    char delim = ' ';

    // 'scalar' mode
    ofstream rate_fs;
    if (trig_mode == 2) {
        char logRateFilename[300];
        sprintf(logRateFilename, "%s.rate", log_filename);
        rate_fs.open(logRateFilename, ios::trunc);
    }

    sprintf(logDataFilename, "%s.acdc", log_filename);
    sprintf(logMetaFilename, "%s.meta", log_filename);
    sprintf(logPedFilename, "%s.ped", log_filename);

    // check if file exists, inquire whether to overwrite
    string temp;
    while (fileExists(logDataFilename)) {
        cout << "file already exists, try new filename: (or enter to overwrite / ctrl-C to quit): ";
        getline(cin, temp);
        if (temp.empty()) break;
        sprintf(logDataFilename, "%s.acdc", temp.c_str());
        sprintf(logMetaFilename, "%s.meta", temp.c_str());
        sprintf(logPedFilename, "%s.ped", temp.c_str());
    }

    /* open up file stream */
    ofstream dataofs, pedofs, metaofs;
    dataofs.open(logDataFilename, ios::trunc);

    /* wraparound_correction, if desired: */
    int baseline[psecSampleCells];
    unwrap_baseline(baseline, 2);
    for (int j = 0; j < psecSampleCells; j++) {
        asic_baseline[j] = baseline[j];
    }

    /* Create header */
    dataofs << "Event" << delim << "Board" << delim << "Ch";
    for (int i = 0; i < psecSampleCells; i++) {
        dataofs << delim << "C" << i;
    }
    dataofs << endl;

    pedofs.open(logPedFilename, ios::trunc);
    // Create Header
    pedofs << "Board" << delim << "Ch";
    for (int i = 0; i < psecSampleCells; i++) {
        pedofs << delim << "C" << i;
    }
    pedofs << endl;

    /* Print out pedestal data */
    for (int board = 0; board < numFrontBoards; board++) {
        // Skip inactive boards
        if (!DC_ACTIVE[board]) continue;
        for (int channel = 0; channel < AC_CHANNELS; channel++) {
            pedofs << board << delim << channel + 1;
            for (int i = 0; i < psecSampleCells; i++) {
                pedofs << delim << PED_DATA[board][channel][i];
            }
            pedofs << endl;
        }
    }

    pedofs.close();

    metaofs.open(logMetaFilename, ios::trunc);

    // Create header
    metaofs << "Event" << delim << "Board" << delim;
    metaofs << "count" << delim << "aa" << delim << "time" << delim << "datetime" << delim
            << "events" << delim << "bin_count_rise" << delim << "self_trig_settings_2" << delim
            << "sys_coincidence_width" << delim << "coincidence_num_chips" << delim
            << "coincidence_num_chans" << delim << "self_trig_settings" << delim
            << "trig_en" << delim << "trig_wait_for_sys" << delim << "trig_rate_only" << delim
            << "trig_sign" << delim << "use_sma_trig_input" << delim
            << "use_coincidence_settings" << delim << "use_trig_valid_as_reset" << delim
            << "coinc_window" << delim << "reg_self_trig" << delim
            << "counts_of_sys_no_local" << delim << "sys_trig_count" << delim
            << "resets_from_firmw" << delim << "firmware_version" << delim
            << "self_trig_mask" << delim << "dig_timestamp_lo" << delim
            << "dig_timestamp_mid" << delim << "dig_timestamp_hi" << delim
            << "dig_event_count" << delim << "event_count" << delim
            << "timestamp_hi" << delim << "timestamp_mid" << delim
            << "timestamp_lo" << delim << "CC_BIN_COUNT" << delim
            << "CC_EVENT_COUNT" << delim << "CC_TIMESTAMP_LO" << delim
            << "CC_TIMESTAMP_MID" << delim << "CC_TIMESTAMP_HI" << delim;
    for (int n = 0; n < 5; n++) metaofs << "ro_cnt_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "ro_target_cnt_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "vbias_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "trigger_threshold_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "ro_dac_value_chip_" << n << delim;
    for (int n = 1; n <= AC_CHANNELS; n++) metaofs << "self_trig_scalar_ch_" << n << delim;
    metaofs << "time_from_valid_to_trig" << delim << "firmware_reset_time" << delim
            << "last_coincidence_num_chans" << endl;

    // read all front end cards
    bool all[numFrontBoards];
    for (int i = 0; i < numFrontBoards; i++) all[i] = true;

    load_ped();

    int number_of_frontend_cards = 0;

    for (int board = 0; board < numFrontBoards; board++) {
        if (DC_ACTIVE[board]) number_of_frontend_cards++;

    }

    cout << "--------------------------------------------------------------" << endl;
    cout << "number of front-end boards detected = " << number_of_frontend_cards
         << " of " << numFrontBoards << " address slots in system" << endl;
    cout << "Trying for " << NUM_READS << " events logged to disk, in a timeout window of "
         << MAX_INT_TIMER << " seconds" << endl;
    cout << "--------------------------------------------------------------" << endl << endl;

    usleep(100000);

    bool reset_event = true;

    // set read mode to NULL
    set_usb_read_mode(0);
    if (mode == USB2x) set_usb_read_mode_slaveDevice(0);
    system_card_trig_valid(false);
    if (mode == USB2x) system_slave_card_trig_valid(false);

    //check system trigger number
    read_CC(false, false, 100);
    int board_trigger = CC_EVENT_COUNT_FROMCC0;
    int last_board_trigger = board_trigger;

    /* cpu time zero */
    timer.start();

    for (int event = 0; event < NUM_READS; event++) {
        set_usb_read_mode(0);
        if (mode == USB2x) set_usb_read_mode_slaveDevice(0);

        time(&now);
        t = timer.stop();
        // interrupt if past specified logging time
        if (t > MAX_INT_TIMER) {
            cout << endl << "readout timed out at " << t << "on event " << event << endl;
            break;
        }

        // trig_mode = 1 is external source or PSEC4 self trigger
        // trig_mode = 0 is over software (USB), i.e. calibration logging
        if (trig_mode == 0) {
            manage_cc_fifo(1);
            if (mode == USB2x) manage_cc_fifo_slaveDevice(1);

            // 'rate-only' mode, only pull data every second
            if (trig_mode == 2) usleep(3e6);

            prep_sync();
            if (mode == USB2x) software_trigger_slaveDevice((unsigned int) 15);
            software_trigger((unsigned int) 15);
            make_sync();

            //acq rate limit
            usleep(LIMIT_READOUT_RATE); // somewhat arbitrary hard-coded rate limitation
            //system_card_trig_valid(false);
            //if(mode == USB2x) system_slave_card_trig_valid(false);
        } else {
            manage_cc_fifo(1);
            if (mode == USB2x) manage_cc_fifo_slaveDevice(1);
            usleep(100);
            for (int iii = 0; iii < 2; iii++) {
                system_card_trig_valid(false);
                if (mode == USB2x) system_slave_card_trig_valid(false);
            }

            //send in trig 'valid' signal
            sys_wait(100);
            prep_sync();
            if (mode == USB2x) system_slave_card_trig_valid(true);
            system_card_trig_valid(true);
            make_sync();
            //}
            //acq rate limit
            usleep(acq_rate + LIMIT_READOUT_RATE);
        }
        int num_pulls = 0;
        int evts = 0;
        int digs = 0;
        while (board_trigger == last_board_trigger && t < MAX_INT_TIMER) {

            read_CC(false, false, 100);
            board_trigger = CC_EVENT_COUNT_FROMCC0;
            cout << "waiting for trigger...     on system event: "
                 << board_trigger << " & readout attempt " << event
                 << " @time " << t << "                        \r";
            cout.flush();
            usleep(1000);
            t = timer.stop();
            num_pulls++;
            if (num_pulls > 100) break;
            //if(num_pulls > 10)  break;   //use this is board trigger does not iterate
        }

        last_board_trigger = board_trigger;
        if (mode == USB2x) system_slave_card_trig_valid(false);
        system_card_trig_valid(false);
        //set_usb_read_mode_slaveDevice(0), set_usb_read_mode(0);
        evts = read_CC(false, false, 0);
        for (int chkdig = 0; chkdig < numFrontBoards; chkdig++)
            digs += DIGITIZING_START_FLAG[chkdig];

        if (evts == 0 || evts != digs) {
            print_to_terminal(event, NUM_READS, CC_EVENT_COUNT_FROMCC0, board_trigger, t);
            cout << "    --NULL--       " << endl;
            reset_event = true;
            event = event - 1;             //repeat event
            continue;
        }

            // show event number at terminal
        else {
            if ((event + 1) % 1 == 0 || event == 0) {
                print_to_terminal(event, NUM_READS, CC_EVENT_COUNT_FROMCC0, board_trigger, t);
                cout << "          \r";
                cout.flush();
            }
        }
        /**************************************/
        //Do bulk read on all front-end cards
        int numBoards = read_AC(1, all, false);
        /**************************************/
        sys_wait(10000);

        for (int jj = 0; jj < 2; jj++) {
            //prep_sync();
            //turn off 'trig valid flag' until checking if data in buffer
            if (mode == USB2x) system_slave_card_trig_valid(false);
            system_card_trig_valid(false);
            if (mode == USB2x) set_usb_read_mode_slaveDevice(0);
            set_usb_read_mode(0);
        }
        reset_event = true; //have event, go ahead and reset for next event

        // form data for filesave
        for (int board = 0; board < numFrontBoards; board++) {
            if (BOARDS_READOUT[board] && numBoards > 0) {
                psec_cnt = 0;
                // assign meta data
                Meta = get_AC_info(false, board, false, event, t, t, evts);
                for (int ch = 0; ch < AC_CHANNELS; ch++) {
                    dataofs << event << delim << board << delim << ch + 1;
                    metaofs << event << delim << board;

                    if (ch > 0 && ch % 6 == 0) psec_cnt++;

                    for (int cell = 0; cell < psecSampleCells; cell++) {
                        sample = adcDat[board]->AC_RAW_DATA[psec_cnt][ch % 6 * 256 + cell];
                        int ped_subtracted = sample - PED_DATA[board][ch][cell];
                        dataofs << delim << dec << ped_subtracted; // std::dec
                        metaofs << delim << adcDat[board]->Meta[cell];
                        adcDat[board]->Data[ch][cell] = (unsigned int) sample;
                    }
                    dataofs << endl;
                    metaofs << endl;
                }
                /* wraparound_correction, if desired: */
                int baseline[psecSampleCells];
                unwrap_baseline(baseline, 2);
                for (int j = 0; j < psecSampleCells; j++) {
                    asic_baseline[j] = baseline[j];
                    adcDat[board]->Meta[j] = Meta[j];
                }
            }
            // if timeout on only some, but not all boards
            else if (numBoards > 0 && BOARDS_TIMEOUT[board] && DC_ACTIVE[board]) {
                for (int i = 0; i < AC_CHANNELS; i++) {
                    if (i > 0 && i % 6 == 0) psec_cnt++;

                    for (int j = 0; j < psecSampleCells; j++) {
                        sample = 0xFF;
                        adcDat[board]->Data[i][j] = sample;
                    }
                }
            }
        }

        last_k = event;

        // LOGGING
    }

    cout << endl;
    cout << "Done on readout:  " << last_k + 1 << " :: @time " << t << " sec" << endl;

    cleanup();

    dump_data();

    if (trig_mode == 2) rate_fs.close();

    cout << "Data saved in file: " << logDataFilename << endl << "*****" << endl;

    dataofs.close();
    pedofs.close();
    metaofs.close();

    return 0;
}

void SuMo::print_to_terminal(int k, int NUM_READS, int cc_event, int board_trig, double t) {
    cout << "Readout:  " << k + 1 << " of " << NUM_READS;
    cout << " :: system|sw evt-" << cc_event << "|" << board_trig;
    cout << " :: evtflags-";
    for (int evt_flag = 0; evt_flag < numFrontBoards; evt_flag++) cout << EVENT_FLAG[evt_flag];
    cout << " :: digflags-";
    for (int dig_flag = 0; dig_flag < numFrontBoards; dig_flag++) cout << DIGITIZING_START_FLAG[dig_flag];
    cout << " :: @time " << t << " sec ";
    //cout.flush();
}
<commit_msg>small output rewrite<commit_after>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <fstream>

#include "SuMo.h"
#include "Timer.h"

using namespace std;
/* subtract pedestal values on-line */
static bool PED_SUBTRCT = false;

static int LIMIT_READOUT_RATE = 6000;  //usecs limit between event polling
static int NUM_SEQ_TIMEOUTS = 100;    // number of sequential timeouts before ending run
const float MAX_INT_TIMER = 800.;    // max cpu timer before ending run (secs)
/* note: usb timeout defined in include/stdUSB.h */

bool overwriteExistingFile = false;

int SuMo::log_data(unsigned int NUM_READS, int trig_mode, int acq_rate, const char *log_filename) {
    int check_event;
    int asic_baseline[psecSampleCells];
    int count = 0;
    int psec_cnt = 0;
    int last_k;
    float _now_, t = 0.;
    Timer timer = Timer();
    time_t now;
    unsigned short sample;
    int *Meta;

    char logDataFilename[300];
    char logMetaFilename[300];
    char logPedFilename[300];
    char delim = ' ';

    // 'scalar' mode
    ofstream rate_fs;
    if (trig_mode == 2) {
        char logRateFilename[300];
        sprintf(logRateFilename, "%s.rate", log_filename);
        rate_fs.open(logRateFilename, ios::trunc);
    }

    sprintf(logDataFilename, "%s.acdc", log_filename);
    sprintf(logMetaFilename, "%s.meta", log_filename);
    sprintf(logPedFilename, "%s.ped", log_filename);

    // check if file exists, inquire whether to overwrite
    string temp;
    while (fileExists(logDataFilename)) {
        cout << "file already exists, try new filename: (or enter to overwrite / ctrl-C to quit): ";
        getline(cin, temp);
        if (temp.empty()) break;
        sprintf(logDataFilename, "%s.acdc", temp.c_str());
        sprintf(logMetaFilename, "%s.meta", temp.c_str());
        sprintf(logPedFilename, "%s.ped", temp.c_str());
    }

    /* open up file stream */
    ofstream dataofs, pedofs, metaofs;
    dataofs.open(logDataFilename, ios::trunc);

    /* wraparound_correction, if desired: */
    int baseline[psecSampleCells];
    unwrap_baseline(baseline, 2);
    for (int j = 0; j < psecSampleCells; j++) {
        asic_baseline[j] = baseline[j];
    }

    /* Create header */
    dataofs << "Event" << delim << "Board" << delim << "Ch";
    for (int i = 0; i < psecSampleCells; i++) {
        dataofs << delim << "C" << i;
    }
    dataofs << endl;

    pedofs.open(logPedFilename, ios::trunc);
    // Create Header
    pedofs << "Board" << delim << "Ch";
    for (int i = 0; i < psecSampleCells; i++) {
        pedofs << delim << "C" << i;
    }
    pedofs << endl;

    /* Print out pedestal data */
    for (int board = 0; board < numFrontBoards; board++) {
        // Skip inactive boards
        if (!DC_ACTIVE[board]) continue;
        for (int channel = 0; channel < AC_CHANNELS; channel++) {
            pedofs << board << delim << channel + 1;
            for (int i = 0; i < psecSampleCells; i++) {
                pedofs << delim << PED_DATA[board][channel][i];
            }
            pedofs << endl;
        }
    }

    pedofs.close();

    metaofs.open(logMetaFilename, ios::trunc);

    // Create header
    metaofs << "Event" << delim << "Board" << delim;
    metaofs << "count" << delim << "aa" << delim << "time" << delim << "datetime" << delim
            << "events" << delim << "bin_count_rise" << delim << "self_trig_settings_2" << delim
            << "sys_coincidence_width" << delim << "coincidence_num_chips" << delim
            << "coincidence_num_chans" << delim << "self_trig_settings" << delim
            << "trig_en" << delim << "trig_wait_for_sys" << delim << "trig_rate_only" << delim
            << "trig_sign" << delim << "use_sma_trig_input" << delim
            << "use_coincidence_settings" << delim << "use_trig_valid_as_reset" << delim
            << "coinc_window" << delim << "reg_self_trig" << delim
            << "counts_of_sys_no_local" << delim << "sys_trig_count" << delim
            << "resets_from_firmw" << delim << "firmware_version" << delim
            << "self_trig_mask" << delim << "dig_timestamp_lo" << delim
            << "dig_timestamp_mid" << delim << "dig_timestamp_hi" << delim
            << "dig_event_count" << delim << "event_count" << delim
            << "timestamp_hi" << delim << "timestamp_mid" << delim
            << "timestamp_lo" << delim << "CC_BIN_COUNT" << delim
            << "CC_EVENT_COUNT" << delim << "CC_TIMESTAMP_LO" << delim
            << "CC_TIMESTAMP_MID" << delim << "CC_TIMESTAMP_HI" << delim;
    for (int n = 0; n < 5; n++) metaofs << "ro_cnt_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "ro_target_cnt_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "vbias_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "trigger_threshold_chip_" << n << delim;
    for (int n = 0; n < 5; n++) metaofs << "ro_dac_value_chip_" << n << delim;
    for (int n = 1; n <= AC_CHANNELS; n++) metaofs << "self_trig_scalar_ch_" << n << delim;
    metaofs << "time_from_valid_to_trig" << delim << "firmware_reset_time" << delim
            << "last_coincidence_num_chans" << endl;

    // read all front end cards
    bool all[numFrontBoards];
    for (int i = 0; i < numFrontBoards; i++) all[i] = true;

    load_ped();

    int number_of_frontend_cards = 0;

    for (int board = 0; board < numFrontBoards; board++) {
        if (DC_ACTIVE[board]) number_of_frontend_cards++;

    }

    cout << "--------------------------------------------------------------" << endl;
    cout << "number of front-end boards detected = " << number_of_frontend_cards
         << " of " << numFrontBoards << " address slots in system" << endl;
    cout << "Trying for " << NUM_READS << " events logged to disk, in a timeout window of "
         << MAX_INT_TIMER << " seconds" << endl;
    cout << "--------------------------------------------------------------" << endl << endl;

    usleep(100000);

    bool reset_event = true;

    // set read mode to NULL
    set_usb_read_mode(0);
    if (mode == USB2x) set_usb_read_mode_slaveDevice(0);
    system_card_trig_valid(false);
    if (mode == USB2x) system_slave_card_trig_valid(false);

    //check system trigger number
    read_CC(false, false, 100);
    int board_trigger = CC_EVENT_COUNT_FROMCC0;
    int last_board_trigger = board_trigger;

    /* cpu time zero */
    timer.start();

    for (int event = 0; event < NUM_READS; event++) {
        set_usb_read_mode(0);
        if (mode == USB2x) set_usb_read_mode_slaveDevice(0);

        time(&now);
        t = timer.stop();
        // interrupt if past specified logging time
        if (t > MAX_INT_TIMER) {
            cout << endl << "readout timed out at " << t << "on event " << event << endl;
            break;
        }

        // trig_mode = 1 is external source or PSEC4 self trigger
        // trig_mode = 0 is over software (USB), i.e. calibration logging
        if (trig_mode == 0) {
            manage_cc_fifo(1);
            if (mode == USB2x) manage_cc_fifo_slaveDevice(1);

            // 'rate-only' mode, only pull data every second
            if (trig_mode == 2) usleep(3e6);

            prep_sync();
            if (mode == USB2x) software_trigger_slaveDevice((unsigned int) 15);
            software_trigger((unsigned int) 15);
            make_sync();

            //acq rate limit
            usleep(LIMIT_READOUT_RATE); // somewhat arbitrary hard-coded rate limitation
            //system_card_trig_valid(false);
            //if(mode == USB2x) system_slave_card_trig_valid(false);
        } else {
            manage_cc_fifo(1);
            if (mode == USB2x) manage_cc_fifo_slaveDevice(1);
            usleep(100);
            for (int iii = 0; iii < 2; iii++) {
                system_card_trig_valid(false);
                if (mode == USB2x) system_slave_card_trig_valid(false);
            }

            //send in trig 'valid' signal
            sys_wait(100);
            prep_sync();
            if (mode == USB2x) system_slave_card_trig_valid(true);
            system_card_trig_valid(true);
            make_sync();
            //}
            //acq rate limit
            usleep(acq_rate + LIMIT_READOUT_RATE);
        }
        int num_pulls = 0;
        int evts = 0;
        int digs = 0;
        while (board_trigger == last_board_trigger && t < MAX_INT_TIMER) {

            read_CC(false, false, 100);
            board_trigger = CC_EVENT_COUNT_FROMCC0;
            cout << "waiting for trigger...     on system event: "
                 << board_trigger << " & readout attempt " << event
                 << " @time " << t << "                        \r";
            cout.flush();
            usleep(1000);
            t = timer.stop();
            num_pulls++;
            if (num_pulls > 100) break;
            //if(num_pulls > 10)  break;   //use this is board trigger does not iterate
        }

        last_board_trigger = board_trigger;
        if (mode == USB2x) system_slave_card_trig_valid(false);
        system_card_trig_valid(false);
        //set_usb_read_mode_slaveDevice(0), set_usb_read_mode(0);
        evts = read_CC(false, false, 0);
        for (int chkdig = 0; chkdig < numFrontBoards; chkdig++)
            digs += DIGITIZING_START_FLAG[chkdig];

        if (evts == 0 || evts != digs) {
            cout << "    --NULL--       " << endl;
            reset_event = true;
            event = event - 1;             //repeat event
            continue;
        }

            // show event number at terminal
        else {
            if ((event + 1) % 1 == 0 || event == 0) {
                print_to_terminal(event, NUM_READS, CC_EVENT_COUNT_FROMCC0, board_trigger, t);
            }
        }
        /**************************************/
        //Do bulk read on all front-end cards
        int numBoards = read_AC(1, all, false);
        /**************************************/
        sys_wait(10000);

        for (int jj = 0; jj < 2; jj++) {
            //prep_sync();
            //turn off 'trig valid flag' until checking if data in buffer
            if (mode == USB2x) system_slave_card_trig_valid(false);
            system_card_trig_valid(false);
            if (mode == USB2x) set_usb_read_mode_slaveDevice(0);
            set_usb_read_mode(0);
        }
        reset_event = true; //have event, go ahead and reset for next event

        // form data for filesave
        for (int board = 0; board < numFrontBoards; board++) {
            if (BOARDS_READOUT[board] && numBoards > 0) {
                psec_cnt = 0;
                // assign meta data
                Meta = get_AC_info(false, board, false, event, t, t, evts);
                for (int ch = 0; ch < AC_CHANNELS; ch++) {
                    dataofs << event << delim << board << delim << ch + 1;
                    metaofs << event << delim << board;

                    if (ch > 0 && ch % 6 == 0) psec_cnt++;

                    for (int cell = 0; cell < psecSampleCells; cell++) {
                        sample = adcDat[board]->AC_RAW_DATA[psec_cnt][ch % 6 * 256 + cell];
                        int ped_subtracted = sample - PED_DATA[board][ch][cell];
                        dataofs << delim << dec << ped_subtracted; // std::dec
                        metaofs << delim << adcDat[board]->Meta[cell];
                        adcDat[board]->Data[ch][cell] = (unsigned int) sample;
                    }
                    dataofs << endl;
                    metaofs << endl;
                }
                /* wraparound_correction, if desired: */
                int baseline[psecSampleCells];
                unwrap_baseline(baseline, 2);
                for (int j = 0; j < psecSampleCells; j++) {
                    asic_baseline[j] = baseline[j];
                    adcDat[board]->Meta[j] = Meta[j];
                }
            }
            // if timeout on only some, but not all boards
            else if (numBoards > 0 && BOARDS_TIMEOUT[board] && DC_ACTIVE[board]) {
                for (int i = 0; i < AC_CHANNELS; i++) {
                    if (i > 0 && i % 6 == 0) psec_cnt++;

                    for (int j = 0; j < psecSampleCells; j++) {
                        sample = 0xFF;
                        adcDat[board]->Data[i][j] = sample;
                    }
                }
            }
        }

        last_k = event;

        // LOGGING
    }

    cout << endl;
    cout << "Done on readout:  " << last_k + 1 << " :: @time " << t << " sec" << endl;

    cleanup();

    dump_data();

    if (trig_mode == 2) rate_fs.close();

    cout << "Data saved in file: " << logDataFilename << endl << "*****" << endl;

    dataofs.close();
    pedofs.close();
    metaofs.close();

    return 0;
}

void SuMo::print_to_terminal(int k, int NUM_READS, int cc_event, int board_trig, double t) {
    cout << "\r" << "Readout:  " << k + 1 << " of " << NUM_READS;
    cout << " :: system|sw evt-" << cc_event << "|" << board_trig;
    cout << " :: evtflags-";
    for (int evt_flag = 0; evt_flag < numFrontBoards; evt_flag++) cout << EVENT_FLAG[evt_flag];
    cout << " :: digflags-";
    for (int dig_flag = 0; dig_flag < numFrontBoards; dig_flag++) cout << DIGITIZING_START_FLAG[dig_flag];
    cout << " :: @time " << t << " sec " << flush;
}
<|endoftext|>


<commit_before>#include "maincontrol.h"

#include <QThread>
#include <QDebug>

quibe::MainControl::MainControl(QObject *parent) :
  QObject(parent) {
  velocidade = 50;

  velocidade_counter = 0;

  QObject::connect(&serial, SIGNAL(mensagemLida(QByteArray)),
                   this, SLOT(parse_message(QByteArray)));
}

void quibe::MainControl::comando_esquerda() {
  serial.enviaComandoMovimento(ComunicacaoSerial::ESQUERDA, velocidade/10);
  qDebug() << "Comando: Esquerda" << endl;
}

void quibe::MainControl::comando_direita() {
  serial.enviaComandoMovimento(ComunicacaoSerial::DIREITA, velocidade/10);
  qDebug() << "Comando: Direita" << endl;
}

void quibe::MainControl::comando_frente() {
  serial.enviaComandoMovimento(ComunicacaoSerial::FRENTE, velocidade/10);
  qDebug() << "Comando: Frente" << endl;
}

void quibe::MainControl::comando_tras() {
  serial.enviaComandoMovimento(ComunicacaoSerial::TRAS, velocidade/10);
  qDebug() << "Comando: Tras" << endl;
}

void quibe::MainControl::comando_subir() {
  serial.enviaComandoMovimento(ComunicacaoSerial::SUBIR, velocidade/10);
  velocidade_counter++;
  //qDebug() << "Comando: Subir" << endl;
  qDebug() << "Velocidade Atual: " << velocidade_counter;
}

void quibe::MainControl::comando_descer() {
  serial.enviaComandoMovimento(ComunicacaoSerial::DESCER, velocidade/10);
  velocidade_counter--;
  //qDebug() << "Comando: Descer" << endl;
  qDebug() << "Velocidade Atual: " << velocidade_counter;
}

void quibe::MainControl::comando_horario() {
  serial.enviaComandoMovimento(ComunicacaoSerial::HORARIO, velocidade/10);
  qDebug() << "Comando: Girar Sentido Horário" << endl;
}

void quibe::MainControl::comando_antihorario() {
  serial.enviaComandoMovimento(ComunicacaoSerial::ANTIHORARIO, velocidade/10);
  qDebug() << "Comando: Girar Sentido Anti-Horário" << endl;
}

void quibe::MainControl::comando_parar() {
  serial.enviaComandoMovimento(ComunicacaoSerial::PARAR, velocidade/10);
  qDebug() << "Comando: Parar" << endl;
}

void quibe::MainControl::conectar_serial(bool conectar, SerialConfig config) {
  if (conectar) {
    bool conectado = serial.conectar(config);
    emit serial_conectado(conectado);
  } else {
    serial.desconectar();
    emit serial_desconectado();
  }
}

void quibe::MainControl::conectar_quadricoptero(bool conectar) {
  if (conectar) {
    serial.enviaHandshake();
  }
  else {
    // Desconectar
  }
}

void quibe::MainControl::comando_decolar_pousar(bool decolar) {
  if (decolar) {
    emit decolou();
  } else emit pousou();
}

void quibe::MainControl::velocidade_alterada(int velocidade) {
  this->velocidade = velocidade;
  qDebug() << "Velocidade alterada para: " << velocidade << "\%" << endl;
}

void quibe::MainControl::parse_message(QByteArray mensagem) {
  switch (mensagem[3]) {
  case ComunicacaoSerial::DIAGNOSTIC:
    qDebug() << "Recebeu mensagem de diagnóstico";
    if (mensagem[4] & ComunicacaoSerial::READY) {
      emit quadricoptero_conectado(true);
    }
    else {
      QThread::currentThread()->sleep(1);
      serial.enviaHandshake();
    }
    break;
  case ComunicacaoSerial::SONAR_DATA:
    qDebug() << "Recebeu dados do sonar";
    uint sensor_cima, sensor_baixo, sensor_frente, sensor_tras, sensor_esquerda, sensor_direita;

    sensor_cima = (((uint)mensagem[4]) << 8) + ((uint)mensagem[5]);
    sensor_baixo = (((uint)mensagem[6]) << 8) + ((uint)mensagem[7]);
    sensor_frente = (((uint)mensagem[8]) << 8) + ((uint)mensagem[9]);
    sensor_tras = (((uint)mensagem[10] << 8)) + ((uint)mensagem[11]);
    sensor_esquerda = (((uint)mensagem[12]) << 8) + ((uint)mensagem[13]);
    sensor_direita = (((uint)mensagem[14]) << 8) + ((uint)mensagem[15]);

    emit dados_sonar_recebidos(sensor_cima, sensor_baixo, sensor_frente,
                               sensor_tras, sensor_esquerda, sensor_direita);

    break;
  case ComunicacaoSerial::MPU6050_DATA:
    int roll, pitch, yaw;

    roll = (((int)mensagem[4]) << 8) + (((int)mensagem[5]) & 0xFF);
    pitch = (((int)mensagem[6]) << 8) + (((int)mensagem[7]) & 0xFF);
    yaw = (((int)mensagem[8]) << 8) + (((int)mensagem[9]) & 0xFF);

    emit dados_angulo_recebidos(roll, pitch, yaw);
    break;
  default:
    qDebug() << "ERRO! Recebida mensagem inesperada.";
    qDebug() << "Data Dump da mensagem:";
    for (int i = 0; i < 8; i++) {
      qDebug() << mensagem.left(4).toHex();
      mensagem.remove(0,4);
    }
    break;
  }
}
<commit_msg>Adicionada divisão dos ângulos na estação base<commit_after>#include "maincontrol.h"

#include <QThread>
#include <QDebug>

quibe::MainControl::MainControl(QObject *parent) :
  QObject(parent) {
  velocidade = 50;

  velocidade_counter = 0;

  QObject::connect(&serial, SIGNAL(mensagemLida(QByteArray)),
                   this, SLOT(parse_message(QByteArray)));
}

void quibe::MainControl::comando_esquerda() {
  serial.enviaComandoMovimento(ComunicacaoSerial::ESQUERDA, velocidade/10);
  qDebug() << "Comando: Esquerda" << endl;
}

void quibe::MainControl::comando_direita() {
  serial.enviaComandoMovimento(ComunicacaoSerial::DIREITA, velocidade/10);
  qDebug() << "Comando: Direita" << endl;
}

void quibe::MainControl::comando_frente() {
  serial.enviaComandoMovimento(ComunicacaoSerial::FRENTE, velocidade/10);
  qDebug() << "Comando: Frente" << endl;
}

void quibe::MainControl::comando_tras() {
  serial.enviaComandoMovimento(ComunicacaoSerial::TRAS, velocidade/10);
  qDebug() << "Comando: Tras" << endl;
}

void quibe::MainControl::comando_subir() {
  serial.enviaComandoMovimento(ComunicacaoSerial::SUBIR, velocidade/10);
  velocidade_counter++;
  //qDebug() << "Comando: Subir" << endl;
  qDebug() << "Velocidade Atual: " << velocidade_counter;
}

void quibe::MainControl::comando_descer() {
  serial.enviaComandoMovimento(ComunicacaoSerial::DESCER, velocidade/10);
  velocidade_counter--;
  //qDebug() << "Comando: Descer" << endl;
  qDebug() << "Velocidade Atual: " << velocidade_counter;
}

void quibe::MainControl::comando_horario() {
  serial.enviaComandoMovimento(ComunicacaoSerial::HORARIO, velocidade/10);
  qDebug() << "Comando: Girar Sentido Horário" << endl;
}

void quibe::MainControl::comando_antihorario() {
  serial.enviaComandoMovimento(ComunicacaoSerial::ANTIHORARIO, velocidade/10);
  qDebug() << "Comando: Girar Sentido Anti-Horário" << endl;
}

void quibe::MainControl::comando_parar() {
  serial.enviaComandoMovimento(ComunicacaoSerial::PARAR, velocidade/10);
  qDebug() << "Comando: Parar" << endl;
}

void quibe::MainControl::conectar_serial(bool conectar, SerialConfig config) {
  if (conectar) {
    bool conectado = serial.conectar(config);
    emit serial_conectado(conectado);
  } else {
    serial.desconectar();
    emit serial_desconectado();
  }
}

void quibe::MainControl::conectar_quadricoptero(bool conectar) {
  if (conectar) {
    serial.enviaHandshake();
  }
  else {
    // Desconectar
  }
}

void quibe::MainControl::comando_decolar_pousar(bool decolar) {
  if (decolar) {
    emit decolou();
  } else emit pousou();
}

void quibe::MainControl::velocidade_alterada(int velocidade) {
  this->velocidade = velocidade;
  qDebug() << "Velocidade alterada para: " << velocidade << "\%" << endl;
}

void quibe::MainControl::parse_message(QByteArray mensagem) {
  switch (mensagem[3]) {
  case ComunicacaoSerial::DIAGNOSTIC:
    qDebug() << "Recebeu mensagem de diagnóstico";
    if (mensagem[4] & ComunicacaoSerial::READY) {
      emit quadricoptero_conectado(true);
    }
    else {
      QThread::currentThread()->sleep(1);
      serial.enviaHandshake();
    }
    break;
  case ComunicacaoSerial::SONAR_DATA:
    qDebug() << "Recebeu dados do sonar";
    uint sensor_cima, sensor_baixo, sensor_frente, sensor_tras, sensor_esquerda, sensor_direita;

    sensor_cima = (((uint)mensagem[4]) << 8) + ((uint)mensagem[5]);
    sensor_baixo = (((uint)mensagem[6]) << 8) + ((uint)mensagem[7]);
    sensor_frente = (((uint)mensagem[8]) << 8) + ((uint)mensagem[9]);
    sensor_tras = (((uint)mensagem[10] << 8)) + ((uint)mensagem[11]);
    sensor_esquerda = (((uint)mensagem[12]) << 8) + ((uint)mensagem[13]);
    sensor_direita = (((uint)mensagem[14]) << 8) + ((uint)mensagem[15]);

    emit dados_sonar_recebidos(sensor_cima, sensor_baixo, sensor_frente,
                               sensor_tras, sensor_esquerda, sensor_direita);

    break;
  case ComunicacaoSerial::MPU6050_DATA:
    int roll, pitch, yaw;

    qDebug() << "Leitura do MPU recebido do micro: " <<  mensagem.toHex();

    roll = (((int)mensagem[4]) << 8) + (((int)mensagem[5]) & 0xFF);
    pitch = (((int)mensagem[6]) << 8) + (((int)mensagem[7]) & 0xFF);
    yaw = (((int)mensagem[8]) << 8) + (((int)mensagem[9]) & 0xFF);

    roll /= 60;
    pitch /= 60;
    yaw /= 60;

    emit dados_angulo_recebidos(roll, pitch, yaw);
    break;
  default:
    qDebug() << "ERRO! Recebida mensagem inesperada.";
    qDebug() << "Data Dump da mensagem:";
    for (int i = 0; i < 8; i++) {
      qDebug() << mensagem.left(4).toHex();
      mensagem.remove(0,4);
    }
    break;
  }
}
<|endoftext|>


<commit_before>#include <include/base/cef_logging.h>
#include <brick/cef_handler.h>
#include "edit_account_window.h"

extern char _binary_window_edit_account_glade_start;
extern char _binary_window_edit_account_glade_size;

namespace {

    static void
    on_save_button(GtkWidget *widget, EditAccountWindow *self) {
      bool secure =
         gtk_combo_box_get_active(self->window_objects_.protocol_chooser) == 0;
      const gchar* domain =
        gtk_entry_get_text(self->window_objects_.domain_entry);
      const gchar* login =
         gtk_entry_get_text(self->window_objects_.login_entry);
      const gchar* password =
         gtk_entry_get_text(GTK_ENTRY(self->window_objects_.password_entry));

      CefRefPtr<Account> check_account(new Account);
      check_account->Set(
         secure,
         domain,
         login,
         password
      );

      Account::AuthResult auth_result = check_account->Auth();
      if (!auth_result.success) {
        std::string body;

        switch (auth_result.error_code) {
          case Account::ERROR_CODE::HTTP:
            body = "HTTP error: " + auth_result.http_error;
            break;
          case Account::ERROR_CODE::CAPTCHA:
            body = "You have exceeded the maximum number of login attempts.\n"
               "Please log in browser first";
            break;
          case Account::ERROR_CODE::OTP:
            body = "Account used two-step authentication.\n"
               "Please use Application Password for authorization";
            break;
          case Account::ERROR_CODE::AUTH:
            body = "Authentication failed.";
            break;
          default:
            body = "An unknown error occurred :(";
            break;
        }

        GtkWidget *dialog = gtk_message_dialog_new_with_markup(
           GTK_WINDOW(self->window_objects_.window),
           GTK_DIALOG_DESTROY_WITH_PARENT,
           GTK_MESSAGE_ERROR,
           GTK_BUTTONS_CLOSE,
           NULL
        );

        gtk_message_dialog_set_markup(GTK_MESSAGE_DIALOG(dialog),
           body.c_str());
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
      }

      self->Save(
         secure,
         std::string(domain),
         std::string(login),
         check_account->GetPassword() // Server may update user password while login
      );
    }

    static void
    on_cancel_button(GtkWidget *widget, EditAccountWindow *self) {
      self->Close();
    }

} // namespace

void
EditAccountWindow::Init(CefRefPtr<Account> account, bool switch_on_save) {
  GtkBuilder *builder = gtk_builder_new ();
  GError* error = NULL;

  if (!gtk_builder_add_from_string(builder, &_binary_window_edit_account_glade_start, (gsize)&_binary_window_edit_account_glade_size, &error))
  {
    LOG(WARNING) << "Failed to build account edditting window: " << error->message;
    g_error_free (error);
  }

  window_objects_.account = account;
  window_objects_.switch_on_save = switch_on_save;
  window_handler_ = GTK_WIDGET(gtk_builder_get_object(builder, "edit_account_dialog"));
  window_objects_.window = window_handler_;
  window_objects_.protocol_chooser = GTK_COMBO_BOX(gtk_builder_get_object(builder, "protocol_selector"));
  window_objects_.domain_entry = GTK_ENTRY(gtk_builder_get_object(builder, "domain_entry"));
  window_objects_.login_entry = GTK_ENTRY(gtk_builder_get_object(builder, "login_entry"));
  window_objects_.password_entry = GTK_ENTRY(gtk_builder_get_object(builder, "password_entry"));

  g_signal_connect(gtk_builder_get_object(builder, "save_button"), "clicked", G_CALLBACK(on_save_button), this);
  g_signal_connect(gtk_builder_get_object(builder, "cancel_button"), "clicked", G_CALLBACK(on_cancel_button), this);

  g_object_unref(builder);

  gtk_entry_set_text(
     window_objects_.domain_entry,
     account->GetDomain().c_str()
  );

  gtk_entry_set_text(
     window_objects_.login_entry,
     account->GetLogin().c_str()
  );

  gtk_entry_set_text(
     window_objects_.password_entry,
     account->GetPassword().c_str()
  );

  gtk_combo_box_set_active(
     window_objects_.protocol_chooser,
     account->IsSecure()? 0: 1
  );
}
<commit_msg>Проверяем не пусты ли домен/логин/пароль перед сохранением.<commit_after>#include <include/base/cef_logging.h>
#include <brick/cef_handler.h>
#include <et/com_err.h>
#include "edit_account_window.h"

extern char _binary_window_edit_account_glade_start;
extern char _binary_window_edit_account_glade_size;

namespace {

    static void
    on_save_button(GtkWidget *widget, EditAccountWindow *self) {
      bool secure =
         gtk_combo_box_get_active(self->window_objects_.protocol_chooser) == 0;
      const gchar* domain =
        gtk_entry_get_text(self->window_objects_.domain_entry);
      const gchar* login =
         gtk_entry_get_text(self->window_objects_.login_entry);
      const gchar* password =
         gtk_entry_get_text(GTK_ENTRY(self->window_objects_.password_entry));

      CefRefPtr<Account> check_account(new Account);
      bool show_error = false;
      std::string error_message;

      if (!strlen(domain)) {
        show_error = true;
        error_message = "Empty domain";
      } else if (!strlen(login)) {
        show_error = true;
        error_message = "Empty login";
      } else if (!strlen(password)) {
        show_error = true;
        error_message = "Empty password";
      }

      if (!show_error) {
        check_account->Set(
           secure,
           domain,
           login,
           password
        );

        Account::AuthResult auth_result = check_account->Auth();
        if (!auth_result.success) {
          show_error = true;

          switch (auth_result.error_code) {
            case Account::ERROR_CODE::HTTP:
              error_message = "HTTP error: " + auth_result.http_error;
              break;
            case Account::ERROR_CODE::CAPTCHA:
              error_message = "You have exceeded the maximum number of login attempts.\n"
                 "Please log in browser first";
              break;
            case Account::ERROR_CODE::OTP:
              error_message = "Account used two-step authentication.\n"
                 "Please use Application Password for authorization";
              break;
            case Account::ERROR_CODE::AUTH:
              error_message = "Authentication failed.";
              break;
            default:
              error_message = "An unknown error occurred :(";
              break;
          }
        }
      }

      if (show_error) {
        GtkWidget *dialog = gtk_message_dialog_new_with_markup(
           GTK_WINDOW(self->window_objects_.window),
           GTK_DIALOG_DESTROY_WITH_PARENT,
           GTK_MESSAGE_ERROR,
           GTK_BUTTONS_CLOSE,
           NULL
        );

        gtk_message_dialog_set_markup(GTK_MESSAGE_DIALOG(dialog),
           error_message.c_str());
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
      }

      self->Save(
         secure,
         std::string(domain),
         std::string(login),
         check_account->GetPassword() // Server may update user password while login
      );
    }

    static void
    on_cancel_button(GtkWidget *widget, EditAccountWindow *self) {
      self->Close();
    }

} // namespace

void
EditAccountWindow::Init(CefRefPtr<Account> account, bool switch_on_save) {
  GtkBuilder *builder = gtk_builder_new ();
  GError* error = NULL;

  if (!gtk_builder_add_from_string(builder, &_binary_window_edit_account_glade_start, (gsize)&_binary_window_edit_account_glade_size, &error))
  {
    LOG(WARNING) << "Failed to build account edditting window: " << error->message;
    g_error_free (error);
  }

  window_objects_.account = account;
  window_objects_.switch_on_save = switch_on_save;
  window_handler_ = GTK_WIDGET(gtk_builder_get_object(builder, "edit_account_dialog"));
  window_objects_.window = window_handler_;
  window_objects_.protocol_chooser = GTK_COMBO_BOX(gtk_builder_get_object(builder, "protocol_selector"));
  window_objects_.domain_entry = GTK_ENTRY(gtk_builder_get_object(builder, "domain_entry"));
  window_objects_.login_entry = GTK_ENTRY(gtk_builder_get_object(builder, "login_entry"));
  window_objects_.password_entry = GTK_ENTRY(gtk_builder_get_object(builder, "password_entry"));

  g_signal_connect(gtk_builder_get_object(builder, "save_button"), "clicked", G_CALLBACK(on_save_button), this);
  g_signal_connect(gtk_builder_get_object(builder, "cancel_button"), "clicked", G_CALLBACK(on_cancel_button), this);

  g_object_unref(builder);

  gtk_entry_set_text(
     window_objects_.domain_entry,
     account->GetDomain().c_str()
  );

  gtk_entry_set_text(
     window_objects_.login_entry,
     account->GetLogin().c_str()
  );

  gtk_entry_set_text(
     window_objects_.password_entry,
     account->GetPassword().c_str()
  );

  gtk_combo_box_set_active(
     window_objects_.protocol_chooser,
     account->IsSecure()? 0: 1
  );
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "ICUBridge.hpp"

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/XalanDecimalFormatSymbols.hpp>

#include <PlatformSupport/DoubleSupport.hpp>

#include <unicode/coll.h>
#include <unicode/dcfmtsym.h>
#include <unicode/decimfmt.h>

#include <Include/XalanAutoPtr.hpp>

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<UChar>					UCharVectorType;
#else
	typedef std::vector<UChar>				UCharVectorType;
#endif

#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
inline void
doCopyData(
			const XalanDOMChar*		theString,
			unsigned int			theStringLength,
			XalanDOMChar*			theBuffer)
{
	// Copy the data, truncating each character...
	for (unsigned int i = 0; i < theStringLength; ++i)
	{
		// There should be no truncation, since XalanDOMChars
		// hold UTF-16 code points, but assert, just in case...
		assert(theString[i] == UChar(theString[i]));

		theBuffer[i] = theString[i];
	}

}
#endif

// Use a stack-based buffer up to this size.
const unsigned int	theStackBufferSize = 200u;

const UnicodeString
ICUBridge::XalanDOMCharStringToUnicodeString(const XalanDOMChar*	theString)
{
	if (theString == 0)
	{
		return UnicodeString();
	}
	else
	{
#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)

		const unsigned int	theLength = length(theString);

		if (theStackBufferSize > theLength)
		{
			XalanDOMChar	theBuffer[theStackBufferSize];

			doCopyData(theString, theLength, theBuffer);

#if U_SIZEOF_WCHAR_T==2
			return ICUUnicodeString((wchar_t*)&theBuffer[0], theLength);
#else
			return ICUUnicodeString(&theBuffer[0], theLength);
#endif
		}
		else
		{
			// Create a buffer to copy out the ICUUnicodeString data...
			UCharVectorType		theBuffer;

			// Resize the buffer appropriately...
			theBuffer.resize(theLength);

#if U_SIZEOF_WCHAR_T==2
			doCopyData(theString, theLength, (XalanDOMChar*)&theBuffer[0]);
#else
			doCopyData(theString, theLength, &theBuffer[0]);
#endif

			assert(theLength == theBuffer.size());

			return ICUUnicodeString(&theBuffer[0], theLength);
		}
#else
		return UnicodeString(theString, length(theString));
#endif
	}
}

const UnicodeString
ICUBridge::XalanDOMStringToUnicodeString(const XalanDOMString&	theString)
{
	// Just call up to the XalanDOMChar* version...
	return XalanDOMCharStringToUnicodeString(c_wstr(theString));
}

const XalanDOMString
ICUBridge::UnicodeStringToXalanDOMString(const UnicodeString&	theString)
{
	const int32_t	theLength = theString.length();

#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)

	// If XalanDOMChar is larger than the ICU's UChar, we have to more work...
	// Create a buffer...
	XalanDOMCharVectorType	theBuffer;

	// Reserve the appropriate amount of space...
	theBuffer.reserve(theLength);

	// Copy the data...
	for (int32_t i = 0; i < theLength; ++i)
	{
		theBuffer.push_back(theString[i]);
	}

	return XalanDOMString(&theBuffer[0], theBuffer.size());

#else

	if (theStackBufferSize > theLength)
	{
		UChar	theBuffer[theStackBufferSize];

		// Extract the data...
		theString.extract(0, theLength, theBuffer);

		return XalanDOMString(theBuffer, theLength);
	}
	else
	{
		// Create a buffer to copy out the ICUUnicodeString data...
		UCharVectorType		theBuffer;

		// Resize the buffer appropriately...
		theBuffer.resize(theLength);

		// Extract the data...
		theString.extract(0, theLength, &theBuffer[0]);

		assert(theLength == int32_t(theBuffer.size()));

		return XalanDOMString(&theBuffer[0], theLength);
	}
#endif
}

void
ICUBridge::UnicodeStringToXalanDOMString(
			const UnicodeString&	theString,
			XalanDOMString&			theResult)
{
#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)

	// If XalanDOMChar is larger than the ICU's UChar, we have to more work.
	// Don't bother to provide the optimized version, just call to the
	// previous function.

	theResult = UnicodeStringToXalanDOMString(theString);

#else

	const int32_t	theLength = theString.length();

	if (theStackBufferSize > theLength)
	{
		UChar	theBuffer[theStackBufferSize];

		// Extract the data...
		theString.extract(0, theLength, theBuffer);

		theResult = XalanDOMString(theBuffer, theLength);
	}
	else
	{
#if defined(XALAN_NO_NAMESPACES)
		typedef vector<UChar>		UCharVectorType;
#else
		typedef std::vector<UChar>	UCharVectorType;
#endif

		// Create a buffer to copy out the ICUUnicodeString data...
		UCharVectorType		theBuffer;

		// Resize the buffer appropriately...
		theBuffer.resize(theLength);

		// Extract the data...
		theString.extract(0, theLength, &theBuffer[0]);

		theResult = XalanDOMString(&theBuffer[0], theBuffer.size());
	}
#endif
}

static void
doFormatNumber(
			const XalanDOMString&				thePattern,
			double								theNumber,
			const XalanDecimalFormatSymbols&	theXalanDFS,
			UErrorCode&							theStatus,
			XalanDOMString&						theResult)
{
	if (theStatus == U_ZERO_ERROR ||
		theStatus == U_USING_DEFAULT_ERROR)
	{
		// Use a XalanAutoPtr, to keep this safe until we construct the DecimalFormat instance.
		XalanAutoPtr<DecimalFormatSymbols>	theDFS(new DecimalFormatSymbols(theStatus));

		// We got a XalanDecimalFormatSymbols, so set the
		// corresponding data in the ICU DecimalFormatSymbols.
		theDFS->setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, theXalanDFS.getZeroDigit());
		theDFS->setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, theXalanDFS.getGroupingSeparator());
		theDFS->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, theXalanDFS.getDecimalSeparator());
		theDFS->setSymbol(DecimalFormatSymbols::kPerMillSymbol, theXalanDFS.getPerMill());
		theDFS->setSymbol(DecimalFormatSymbols::kPercentSymbol, theXalanDFS.getPercent());
		theDFS->setSymbol(DecimalFormatSymbols::kDigitSymbol, theXalanDFS.getDigit());
		theDFS->setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, theXalanDFS.getPatternSeparator());

		theDFS->setSymbol(DecimalFormatSymbols::kInfinitySymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getInfinity()));
		theDFS->setSymbol(DecimalFormatSymbols::kNaNSymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getNaN()));
		theDFS->setSymbol(DecimalFormatSymbols::kMinusSignSymbol, theXalanDFS.getMinusSign());
		theDFS->setSymbol(DecimalFormatSymbols::kCurrencySymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getCurrencySymbol()));
		theDFS->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getInternationalCurrencySymbol()));
		theDFS->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, theXalanDFS.getMonetaryDecimalSeparator());

		UnicodeString	theUnicodeResult;

		// Construct a DecimalFormat.  Note that we release the XalanAutoPtr, since the
		// DecimalFormat will adopt the DecimalFormatSymbols instance.
		DecimalFormat	theFormatter(ICUBridge::XalanDOMStringToUnicodeString(thePattern), theDFS.release(), theStatus);

		if (theStatus == U_ZERO_ERROR ||
		    (theStatus >= U_ERROR_INFO_START && theStatus < U_ERROR_INFO_LIMIT))
		{
			// Do the format...
			theFormatter.format(theNumber, theUnicodeResult);

			ICUBridge::UnicodeStringToXalanDOMString(theUnicodeResult, theResult);

			theStatus = U_ZERO_ERROR;
		}
	}
}

unsigned long
ICUBridge::FormatNumber(
			const XalanDOMString&				thePattern,
			double								theNumber,
			const XalanDecimalFormatSymbols*	theXalanDFS,
			XalanDOMString&						theResult)
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	if (theXalanDFS == 0)
	{
		XalanDecimalFormatSymbols	theDefaultSymbols;

		doFormatNumber(
				thePattern,
				theNumber,
				theDefaultSymbols,
				theStatus,
				theResult);
	}
	else
	{
		doFormatNumber(
				thePattern,
				theNumber,
				*theXalanDFS,
				theStatus,
				theResult);
	}

	return theStatus;
}

int
ICUBridge::collationCompare(
			const XalanDOMString&	theLHS,
			const XalanDOMString&	theRHS)
{
	// Just call to the XalanDOMChar* version...
	return collationCompare(c_wstr(theLHS), c_wstr(theRHS));
}

int
ICUBridge::collationCompare(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS)
{
	UErrorCode				theStatus = U_ZERO_ERROR;

	// Create a collator, and keep it in an XalanAutoPtr...
	const XalanAutoPtr<Collator>	theCollator(Collator::createInstance(theStatus));

	if (theStatus == U_ZERO_ERROR || theStatus == U_USING_DEFAULT_ERROR)
	{
		// OK, do the compare...
		return theCollator->compare(
#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
					ICUBridge::XalanDOMCharStringToUnicodeString(theLHS),
					ICUBridge::XalanDOMCharStringToUnicodeString(theRHS));
#else
					theLHS,
					length(theLHS),
					theRHS,
					length(theRHS));
#endif
	}
	else
	{
		// If creating the ICU Collator failed, fall back to the default...
		return collationCompare(theLHS, theRHS);
	}
}
<commit_msg>Fixed bogus class name.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "ICUBridge.hpp"

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/XalanDecimalFormatSymbols.hpp>

#include <PlatformSupport/DoubleSupport.hpp>

#include <unicode/coll.h>
#include <unicode/dcfmtsym.h>
#include <unicode/decimfmt.h>

#include <Include/XalanAutoPtr.hpp>

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<UChar>					UCharVectorType;
#else
	typedef std::vector<UChar>				UCharVectorType;
#endif

#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
inline void
doCopyData(
			const XalanDOMChar*		theString,
			unsigned int			theStringLength,
			XalanDOMChar*			theBuffer)
{
	// Copy the data, truncating each character...
	for (unsigned int i = 0; i < theStringLength; ++i)
	{
		// There should be no truncation, since XalanDOMChars
		// hold UTF-16 code points, but assert, just in case...
		assert(theString[i] == UChar(theString[i]));

		theBuffer[i] = theString[i];
	}

}
#endif

// Use a stack-based buffer up to this size.
const unsigned int	theStackBufferSize = 200u;

const UnicodeString
ICUBridge::XalanDOMCharStringToUnicodeString(const XalanDOMChar*	theString)
{
	if (theString == 0)
	{
		return UnicodeString();
	}
	else
	{
#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)

		const unsigned int	theLength = length(theString);

		if (theStackBufferSize > theLength)
		{
			XalanDOMChar	theBuffer[theStackBufferSize];

			doCopyData(theString, theLength, theBuffer);

#if U_SIZEOF_WCHAR_T==2
			return UnicodeString((wchar_t*)&theBuffer[0], theLength);
#else
			return UnicodeString(&theBuffer[0], theLength);
#endif
		}
		else
		{
			// Create a buffer to copy out the UnicodeString data...
			UCharVectorType		theBuffer;

			// Resize the buffer appropriately...
			theBuffer.resize(theLength);

#if U_SIZEOF_WCHAR_T==2
			doCopyData(theString, theLength, (XalanDOMChar*)&theBuffer[0]);
#else
			doCopyData(theString, theLength, &theBuffer[0]);
#endif

			assert(theLength == theBuffer.size());

			return UnicodeString(&theBuffer[0], theLength);
		}
#else
		return UnicodeString(theString, length(theString));
#endif
	}
}

const UnicodeString
ICUBridge::XalanDOMStringToUnicodeString(const XalanDOMString&	theString)
{
	// Just call up to the XalanDOMChar* version...
	return XalanDOMCharStringToUnicodeString(c_wstr(theString));
}

const XalanDOMString
ICUBridge::UnicodeStringToXalanDOMString(const UnicodeString&	theString)
{
	const int32_t	theLength = theString.length();

#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)

	// If XalanDOMChar is larger than the ICU's UChar, we have to more work...
	// Create a buffer...
	XalanDOMCharVectorType	theBuffer;

	// Reserve the appropriate amount of space...
	theBuffer.reserve(theLength);

	// Copy the data...
	for (int32_t i = 0; i < theLength; ++i)
	{
		theBuffer.push_back(theString[i]);
	}

	return XalanDOMString(&theBuffer[0], theBuffer.size());

#else

	if (theStackBufferSize > theLength)
	{
		UChar	theBuffer[theStackBufferSize];

		// Extract the data...
		theString.extract(0, theLength, theBuffer);

		return XalanDOMString(theBuffer, theLength);
	}
	else
	{
		// Create a buffer to copy out the UnicodeString data...
		UCharVectorType		theBuffer;

		// Resize the buffer appropriately...
		theBuffer.resize(theLength);

		// Extract the data...
		theString.extract(0, theLength, &theBuffer[0]);

		assert(theLength == int32_t(theBuffer.size()));

		return XalanDOMString(&theBuffer[0], theLength);
	}
#endif
}

void
ICUBridge::UnicodeStringToXalanDOMString(
			const UnicodeString&	theString,
			XalanDOMString&			theResult)
{
#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)

	// If XalanDOMChar is larger than the ICU's UChar, we have to more work.
	// Don't bother to provide the optimized version, just call to the
	// previous function.

	theResult = UnicodeStringToXalanDOMString(theString);

#else

	const int32_t	theLength = theString.length();

	if (theStackBufferSize > theLength)
	{
		UChar	theBuffer[theStackBufferSize];

		// Extract the data...
		theString.extract(0, theLength, theBuffer);

		theResult = XalanDOMString(theBuffer, theLength);
	}
	else
	{
#if defined(XALAN_NO_NAMESPACES)
		typedef vector<UChar>		UCharVectorType;
#else
		typedef std::vector<UChar>	UCharVectorType;
#endif

		// Create a buffer to copy out the UnicodeString data...
		UCharVectorType		theBuffer;

		// Resize the buffer appropriately...
		theBuffer.resize(theLength);

		// Extract the data...
		theString.extract(0, theLength, &theBuffer[0]);

		theResult = XalanDOMString(&theBuffer[0], theBuffer.size());
	}
#endif
}

static void
doFormatNumber(
			const XalanDOMString&				thePattern,
			double								theNumber,
			const XalanDecimalFormatSymbols&	theXalanDFS,
			UErrorCode&							theStatus,
			XalanDOMString&						theResult)
{
	if (theStatus == U_ZERO_ERROR ||
		theStatus == U_USING_DEFAULT_ERROR)
	{
		// Use a XalanAutoPtr, to keep this safe until we construct the DecimalFormat instance.
		XalanAutoPtr<DecimalFormatSymbols>	theDFS(new DecimalFormatSymbols(theStatus));

		// We got a XalanDecimalFormatSymbols, so set the
		// corresponding data in the ICU DecimalFormatSymbols.
		theDFS->setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, theXalanDFS.getZeroDigit());
		theDFS->setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, theXalanDFS.getGroupingSeparator());
		theDFS->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, theXalanDFS.getDecimalSeparator());
		theDFS->setSymbol(DecimalFormatSymbols::kPerMillSymbol, theXalanDFS.getPerMill());
		theDFS->setSymbol(DecimalFormatSymbols::kPercentSymbol, theXalanDFS.getPercent());
		theDFS->setSymbol(DecimalFormatSymbols::kDigitSymbol, theXalanDFS.getDigit());
		theDFS->setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, theXalanDFS.getPatternSeparator());

		theDFS->setSymbol(DecimalFormatSymbols::kInfinitySymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getInfinity()));
		theDFS->setSymbol(DecimalFormatSymbols::kNaNSymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getNaN()));
		theDFS->setSymbol(DecimalFormatSymbols::kMinusSignSymbol, theXalanDFS.getMinusSign());
		theDFS->setSymbol(DecimalFormatSymbols::kCurrencySymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getCurrencySymbol()));
		theDFS->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, ICUBridge::XalanDOMStringToUnicodeString(theXalanDFS.getInternationalCurrencySymbol()));
		theDFS->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, theXalanDFS.getMonetaryDecimalSeparator());

		UnicodeString	theUnicodeResult;

		// Construct a DecimalFormat.  Note that we release the XalanAutoPtr, since the
		// DecimalFormat will adopt the DecimalFormatSymbols instance.
		DecimalFormat	theFormatter(ICUBridge::XalanDOMStringToUnicodeString(thePattern), theDFS.release(), theStatus);

		if (theStatus == U_ZERO_ERROR ||
		    (theStatus >= U_ERROR_INFO_START && theStatus < U_ERROR_INFO_LIMIT))
		{
			// Do the format...
			theFormatter.format(theNumber, theUnicodeResult);

			ICUBridge::UnicodeStringToXalanDOMString(theUnicodeResult, theResult);

			theStatus = U_ZERO_ERROR;
		}
	}
}

unsigned long
ICUBridge::FormatNumber(
			const XalanDOMString&				thePattern,
			double								theNumber,
			const XalanDecimalFormatSymbols*	theXalanDFS,
			XalanDOMString&						theResult)
{
	UErrorCode	theStatus = U_ZERO_ERROR;

	if (theXalanDFS == 0)
	{
		XalanDecimalFormatSymbols	theDefaultSymbols;

		doFormatNumber(
				thePattern,
				theNumber,
				theDefaultSymbols,
				theStatus,
				theResult);
	}
	else
	{
		doFormatNumber(
				thePattern,
				theNumber,
				*theXalanDFS,
				theStatus,
				theResult);
	}

	return theStatus;
}

int
ICUBridge::collationCompare(
			const XalanDOMString&	theLHS,
			const XalanDOMString&	theRHS)
{
	// Just call to the XalanDOMChar* version...
	return collationCompare(c_wstr(theLHS), c_wstr(theRHS));
}

int
ICUBridge::collationCompare(
			const XalanDOMChar*		theLHS,
			const XalanDOMChar*		theRHS)
{
	UErrorCode				theStatus = U_ZERO_ERROR;

	// Create a collator, and keep it in an XalanAutoPtr...
	const XalanAutoPtr<Collator>	theCollator(Collator::createInstance(theStatus));

	if (theStatus == U_ZERO_ERROR || theStatus == U_USING_DEFAULT_ERROR)
	{
		// OK, do the compare...
		return theCollator->compare(
#if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH)
					ICUBridge::XalanDOMCharStringToUnicodeString(theLHS),
					ICUBridge::XalanDOMCharStringToUnicodeString(theRHS));
#else
					theLHS,
					length(theLHS),
					theRHS,
					length(theRHS));
#endif
	}
	else
	{
		// If creating the ICU Collator failed, fall back to the default...
		return collationCompare(theLHS, theRHS);
	}
}
<|endoftext|>


<commit_before>/*
  This file is part of KDE Kontact.

  Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
 */

#include <qptrlist.h>
#include <qwidgetstack.h>
#include <qsignal.h>
#include <qobjectlist.h>
#include <qlabel.h>
#include <qimage.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qfontmetrics.h>
#include <qsignalmapper.h>
#include <qstyle.h>
#include <qframe.h>
#include <qdrawutil.h>

#include <kpopupmenu.h>
#include <kapplication.h>
#include <kdialog.h>
#include <klocale.h>
#include <kiconloader.h>
#include <sidebarextension.h>

#include <kdebug.h>

#include "mainwindow.h"

#include "plugin.h"

#include "prefs.h"
#include "iconsidepane.h"

namespace Kontact
{

//ugly wrapper class for adding an operator< to the Plugin class

class PluginProxy
{
  public:
    PluginProxy()
      : mPlugin( 0 )
    { }

    PluginProxy( Plugin *plugin )
      : mPlugin( plugin )
    { }

    PluginProxy & operator=( Plugin *plugin )
    {
      mPlugin = plugin;
      return *this;
    }

    bool operator<( PluginProxy &rhs ) const
    {
      return mPlugin->weight() < rhs.mPlugin->weight();
    }

    Plugin *plugin() const
    {
      return mPlugin;
    }

  private:
    Plugin *mPlugin;
};

} //namespace

using namespace Kontact;

EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin )
  : QListBoxItem( parent ),
    mPlugin( plugin )
{
  reloadPixmap();
  setCustomHighlighting( true );
  setText( plugin->title() );
}

EntryItem::~EntryItem()
{
}

void EntryItem::reloadPixmap()
{
  int size = (int)navigator()->viewMode();
  if ( size != 0 )
    mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(),
                                               KIcon::Desktop, size );
  else
    mPixmap = QPixmap();
}

Navigator* EntryItem::navigator() const
{
  return static_cast<Navigator*>( listBox() );
}

int EntryItem::width( const QListBox *listbox ) const
{
  int w;
  if ( text().isEmpty() )
    w = mPixmap.width();
  else if (navigator()->viewMode() > SmallIcons)
    w = QMAX( (int)navigator()->viewMode(), listbox->fontMetrics().width( text() ) );
  else
    w = (int)navigator()->viewMode() + 4 + listbox->fontMetrics().width( text() );

  return w + ( KDialog::marginHint() * 2 );
}

int EntryItem::height( const QListBox *listbox ) const
{
  int h;
  if ( text().isEmpty() )
    h = mPixmap.height() + 4;
  else if (navigator()->viewMode() > SmallIcons)
    h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
  else
    h = QMAX( (int)navigator()->viewMode(),
              listbox->fontMetrics().lineSpacing() ) +
              KDialog::spacingHint() * 2;

  return h;
}

void EntryItem::paint( QPainter *p )
{
  reloadPixmap();

  QListBox *box = listBox();
  bool iconAboveText = navigator()->viewMode() > SmallIcons;
  int w = box->viewport()->width();
  int y = iconAboveText ? 2 : KDialog::spacingHint();

  // draw selected
  if ( isCurrent() || isSelected() ) {
    int h = height( box );

    QBrush brush = box->colorGroup().brush( QColorGroup::Highlight );
    brush.setColor( brush.color().light( 115 ) );
    p->fillRect( 1, 0, w - 2, h - 1, brush );
    QPen pen = p->pen();
    QPen oldPen = pen;
    pen.setColor( box->colorGroup().mid() );
    p->setPen( pen );

    p->drawPoint( 1, 0 );
    p->drawPoint( 1, h - 2 );
    p->drawPoint( w - 2, 0 );
    p->drawPoint( w - 2, h - 2 );

    p->setPen( oldPen );
  }

  if ( !mPixmap.isNull() ) {
      int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) : KDialog::marginHint();
    p->drawPixmap( x, y, mPixmap );
  }

  QColor shadowColor = listBox()->colorGroup().background().dark(115);
  if ( isCurrent() || isSelected() ) {
    p->setPen( box->colorGroup().highlightedText() );
  }

  if ( !text().isEmpty() ) {
    QFontMetrics fm = p->fontMetrics();

    int x = 0;
    if (iconAboveText) {
      x = ( w - fm.width( text() ) ) / 2;
      y += fm.height() - fm.descent() + mPixmap.height();
    }
    else {
      x = KDialog::marginHint() + mPixmap.width() + 4;

      if ( mPixmap.height() < fm.height() )
        y += fm.ascent() + fm.leading()/2;
      else
        y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
    }

    if ( isCurrent() || isSelected() ) {
      p->setPen( box->colorGroup().highlight().dark(115) );
      p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1),
                   y + 1, text() );
      p->setPen( box->colorGroup().highlightedText() );
    }
    else
      p->setPen( box->colorGroup().text() );

    p->drawText( x, y, text() );
  }
}

Navigator::Navigator( SidePaneBase *parent, const char *name )
  : KListBox( parent, name ), mSidePane( parent )
{
  mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() );
  setSelectionMode( KListBox::Single );
  viewport()->setBackgroundMode( PaletteBackground );
  setHScrollBarMode( QScrollView::AlwaysOff );
  setAcceptDrops( true );

  setFocusPolicy( NoFocus );

  connect( this, SIGNAL( selectionChanged( QListBoxItem* ) ),
           SLOT( slotExecuted( QListBoxItem* ) ) );

  connect( this, SIGNAL( rightButtonPressed( QListBoxItem*, const QPoint& ) ),
           SLOT( slotShowRMBMenu( QListBoxItem*, const QPoint& ) ) );

  mMapper = new QSignalMapper( this );
  connect( mMapper, SIGNAL( mapped( int ) ), SLOT( shortCutSelected( int ) ) );
}

QSize Navigator::sizeHint() const
{
  return QSize( 100, 100 );
}

void Navigator::setSelected( QListBoxItem *item, bool selected )
{
  // Reimplemented to avoid the immediate activation of
  // the item. might turn out it doesn't work, we check that
  // an confirm from MainWindow::selectPlugin()
  if ( selected ) {
    EntryItem *entry = static_cast<EntryItem*>( item );
    emit pluginActivated( entry->plugin() );
  }
}

void Navigator::updatePlugins( QValueList<Kontact::Plugin*> plugins_ )
{
  QValueList<Kontact::PluginProxy> plugins;
  QValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end();
  QValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin();
  for ( ; it_ != end_; ++it_ )
    plugins += PluginProxy( *it_ );

  clear();

  mActions.setAutoDelete( true );
  mActions.clear();
  mActions.setAutoDelete( false );

  int counter = 0;
  int minWidth = 0;
  qBubbleSort( plugins );
  QValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end();
  QValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin();
  for ( ; it != end; ++it ) {
    Kontact::Plugin *plugin = ( *it ).plugin();
    if ( !plugin->showInSideBar() )
      continue;

    EntryItem *item = new EntryItem( this, plugin );

    if ( item->width( this ) > minWidth )
      minWidth = item->width( this );

    QString name = QString( "CTRL+%1" ).arg( counter + 1 );
    KAction *action = new KAction( plugin->title(), KShortcut( name ),
                                   mMapper, SLOT( map() ),
                                   mSidePane->actionCollection(), name.latin1() );
    mMapper->setMapping( action, counter );
    counter++;
  }

  parentWidget()->setFixedWidth( minWidth );
}

void Navigator::dragEnterEvent( QDragEnterEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  dragMoveEvent( event );
}

void Navigator::dragMoveEvent( QDragMoveEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  kdDebug(5600) << "  Format: " << event->format() << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    event->accept( false );
    return;
  }

  EntryItem *entry = static_cast<EntryItem*>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  event->accept( entry->plugin()->canDecodeDrag( event ) );
}

void Navigator::dropEvent( QDropEvent *event )
{
  kdDebug(5600) << "Navigator::dropEvent()" << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    return;
  }

  EntryItem *entry = static_cast<EntryItem*>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  entry->plugin()->processDropEvent( event );
}

void Navigator::resizeEvent( QResizeEvent *event )
{
  QListBox::resizeEvent( event );
  triggerUpdate( true );
}

void Navigator::slotExecuted( QListBoxItem *item )
{
  if ( !item )
    return;

  EntryItem *entry = static_cast<EntryItem*>( item );

  emit pluginActivated( entry->plugin() );
}

IconViewMode Navigator::sizeIntToEnum(int size) const
{
  switch ( size ) {
    case int(LargeIcons):
      return LargeIcons;
      break;
    case int(NormalIcons):
      return NormalIcons;
      break;
    case int(SmallIcons):
      return SmallIcons;
      break;
    case int(TextOnly):
      return TextOnly;
      break;
    default:
      // Stick with sane values
      return NormalIcons;
      kdDebug() << "View mode not implemented!" << endl;
      break;
  }
}

void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint &pos )
{
  KPopupMenu menu;
  menu.insertTitle( i18n( "Icon Size" ) );
  menu.insertItem( i18n( "Large" ), (int)LargeIcons );
  menu.insertItem( i18n( "Normal" ), (int)NormalIcons );
  menu.insertItem( i18n( "Small" ), (int)SmallIcons );
  menu.insertItem( i18n( "Text Only" ), (int)TextOnly );
  int choice = menu.exec( pos );

  if ( choice == -1 )
    return;

  mViewMode = sizeIntToEnum( choice );
  Prefs::self()->setSidePaneIconSize( choice );

  int maxWidth = 0;
  QListBoxItem* it = 0;
  for (int i = 0; (it = item(i)) != 0; ++i)
  {
    int width = it->width(this);
    if (width > maxWidth)
      maxWidth = width;
  }
  parentWidget()->setFixedWidth( maxWidth );

  triggerUpdate( true );
}

void Navigator::shortCutSelected( int pos )
{
  setCurrentItem( pos );
}

IconSidePane::IconSidePane( Core *core, QWidget *parent, const char *name )
  : SidePaneBase( core, parent, name )
{
  mNavigator = new Navigator( this );
  connect( mNavigator, SIGNAL( pluginActivated( Kontact::Plugin* ) ),
           SIGNAL( pluginSelected( Kontact::Plugin* ) ) );

  setAcceptDrops( true );
}

IconSidePane::~IconSidePane()
{
}

void IconSidePane::updatePlugins()
{
  mNavigator->updatePlugins( core()->pluginList() );
}

void IconSidePane::selectPlugin( Kontact::Plugin *plugin )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
    if ( item->plugin() == plugin ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

void IconSidePane::selectPlugin( const QString &name )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
    if ( item->plugin()->identifier() == name ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

#include "iconsidepane.moc"

// vim: sw=2 sts=2 et tw=80
<commit_msg>don't lighten the color. was from an earlier experiment. sorry cornelius.<commit_after>/*
  This file is part of KDE Kontact.

  Copyright (C) 2003 Cornelius Schumacher <schumacher@kde.org>

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
 */

#include <qptrlist.h>
#include <qwidgetstack.h>
#include <qsignal.h>
#include <qobjectlist.h>
#include <qlabel.h>
#include <qimage.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qfontmetrics.h>
#include <qsignalmapper.h>
#include <qstyle.h>
#include <qframe.h>
#include <qdrawutil.h>

#include <kpopupmenu.h>
#include <kapplication.h>
#include <kdialog.h>
#include <klocale.h>
#include <kiconloader.h>
#include <sidebarextension.h>

#include <kdebug.h>

#include "mainwindow.h"

#include "plugin.h"

#include "prefs.h"
#include "iconsidepane.h"

namespace Kontact
{

//ugly wrapper class for adding an operator< to the Plugin class

class PluginProxy
{
  public:
    PluginProxy()
      : mPlugin( 0 )
    { }

    PluginProxy( Plugin *plugin )
      : mPlugin( plugin )
    { }

    PluginProxy & operator=( Plugin *plugin )
    {
      mPlugin = plugin;
      return *this;
    }

    bool operator<( PluginProxy &rhs ) const
    {
      return mPlugin->weight() < rhs.mPlugin->weight();
    }

    Plugin *plugin() const
    {
      return mPlugin;
    }

  private:
    Plugin *mPlugin;
};

} //namespace

using namespace Kontact;

EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin )
  : QListBoxItem( parent ),
    mPlugin( plugin )
{
  reloadPixmap();
  setCustomHighlighting( true );
  setText( plugin->title() );
}

EntryItem::~EntryItem()
{
}

void EntryItem::reloadPixmap()
{
  int size = (int)navigator()->viewMode();
  if ( size != 0 )
    mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(),
                                               KIcon::Desktop, size );
  else
    mPixmap = QPixmap();
}

Navigator* EntryItem::navigator() const
{
  return static_cast<Navigator*>( listBox() );
}

int EntryItem::width( const QListBox *listbox ) const
{
  int w;
  if ( text().isEmpty() )
    w = mPixmap.width();
  else if (navigator()->viewMode() > SmallIcons)
    w = QMAX( (int)navigator()->viewMode(), listbox->fontMetrics().width( text() ) );
  else
    w = (int)navigator()->viewMode() + 4 + listbox->fontMetrics().width( text() );

  return w + ( KDialog::marginHint() * 2 );
}

int EntryItem::height( const QListBox *listbox ) const
{
  int h;
  if ( text().isEmpty() )
    h = mPixmap.height() + 4;
  else if (navigator()->viewMode() > SmallIcons)
    h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
  else
    h = QMAX( (int)navigator()->viewMode(),
              listbox->fontMetrics().lineSpacing() ) +
              KDialog::spacingHint() * 2;

  return h;
}

void EntryItem::paint( QPainter *p )
{
  reloadPixmap();

  QListBox *box = listBox();
  bool iconAboveText = navigator()->viewMode() > SmallIcons;
  int w = box->viewport()->width();
  int y = iconAboveText ? 2 : KDialog::spacingHint();

  // draw selected
  if ( isCurrent() || isSelected() ) {
    int h = height( box );

    QBrush brush = box->colorGroup().brush( QColorGroup::Highlight );
    p->fillRect( 1, 0, w - 2, h - 1, brush );
    QPen pen = p->pen();
    QPen oldPen = pen;
    pen.setColor( box->colorGroup().mid() );
    p->setPen( pen );

    p->drawPoint( 1, 0 );
    p->drawPoint( 1, h - 2 );
    p->drawPoint( w - 2, 0 );
    p->drawPoint( w - 2, h - 2 );

    p->setPen( oldPen );
  }

  if ( !mPixmap.isNull() ) {
      int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) :
                              KDialog::marginHint();
    p->drawPixmap( x, y, mPixmap );
  }

  QColor shadowColor = listBox()->colorGroup().background().dark(115);
  if ( isCurrent() || isSelected() ) {
    p->setPen( box->colorGroup().highlightedText() );
  }

  if ( !text().isEmpty() ) {
    QFontMetrics fm = p->fontMetrics();

    int x = 0;
    if (iconAboveText) {
      x = ( w - fm.width( text() ) ) / 2;
      y += fm.height() - fm.descent() + mPixmap.height();
    }
    else {
      x = KDialog::marginHint() + mPixmap.width() + 4;

      if ( mPixmap.height() < fm.height() )
        y += fm.ascent() + fm.leading()/2;
      else
        y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
    }

    if ( isCurrent() || isSelected() ) {
      p->setPen( box->colorGroup().highlight().dark(115) );
      p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1),
                   y + 1, text() );
      p->setPen( box->colorGroup().highlightedText() );
    }
    else
      p->setPen( box->colorGroup().text() );

    p->drawText( x, y, text() );
  }
}

Navigator::Navigator( SidePaneBase *parent, const char *name )
  : KListBox( parent, name ), mSidePane( parent )
{
  mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() );
  setSelectionMode( KListBox::Single );
  viewport()->setBackgroundMode( PaletteBackground );
  setHScrollBarMode( QScrollView::AlwaysOff );
  setAcceptDrops( true );

  setFocusPolicy( NoFocus );

  connect( this, SIGNAL( selectionChanged( QListBoxItem* ) ),
           SLOT( slotExecuted( QListBoxItem* ) ) );

  connect( this, SIGNAL( rightButtonPressed( QListBoxItem*, const QPoint& ) ),
           SLOT( slotShowRMBMenu( QListBoxItem*, const QPoint& ) ) );

  mMapper = new QSignalMapper( this );
  connect( mMapper, SIGNAL( mapped( int ) ), SLOT( shortCutSelected( int ) ) );
}

QSize Navigator::sizeHint() const
{
  return QSize( 100, 100 );
}

void Navigator::setSelected( QListBoxItem *item, bool selected )
{
  // Reimplemented to avoid the immediate activation of
  // the item. might turn out it doesn't work, we check that
  // an confirm from MainWindow::selectPlugin()
  if ( selected ) {
    EntryItem *entry = static_cast<EntryItem*>( item );
    emit pluginActivated( entry->plugin() );
  }
}

void Navigator::updatePlugins( QValueList<Kontact::Plugin*> plugins_ )
{
  QValueList<Kontact::PluginProxy> plugins;
  QValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end();
  QValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin();
  for ( ; it_ != end_; ++it_ )
    plugins += PluginProxy( *it_ );

  clear();

  mActions.setAutoDelete( true );
  mActions.clear();
  mActions.setAutoDelete( false );

  int counter = 0;
  int minWidth = 0;
  qBubbleSort( plugins );
  QValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end();
  QValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin();
  for ( ; it != end; ++it ) {
    Kontact::Plugin *plugin = ( *it ).plugin();
    if ( !plugin->showInSideBar() )
      continue;

    EntryItem *item = new EntryItem( this, plugin );

    if ( item->width( this ) > minWidth )
      minWidth = item->width( this );

    QString name = QString( "CTRL+%1" ).arg( counter + 1 );
    KAction *action = new KAction( plugin->title(), KShortcut( name ),
                                   mMapper, SLOT( map() ),
                                   mSidePane->actionCollection(), name.latin1() );
    mMapper->setMapping( action, counter );
    counter++;
  }

  parentWidget()->setFixedWidth( minWidth );
}

void Navigator::dragEnterEvent( QDragEnterEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  dragMoveEvent( event );
}

void Navigator::dragMoveEvent( QDragMoveEvent *event )
{
  kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;

  kdDebug(5600) << "  Format: " << event->format() << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    event->accept( false );
    return;
  }

  EntryItem *entry = static_cast<EntryItem*>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  event->accept( entry->plugin()->canDecodeDrag( event ) );
}

void Navigator::dropEvent( QDropEvent *event )
{
  kdDebug(5600) << "Navigator::dropEvent()" << endl;

  QListBoxItem *item = itemAt( event->pos() );

  if ( !item ) {
    return;
  }

  EntryItem *entry = static_cast<EntryItem*>( item );

  kdDebug(5600) << "  PLUGIN: " << entry->plugin()->identifier() << endl;

  entry->plugin()->processDropEvent( event );
}

void Navigator::resizeEvent( QResizeEvent *event )
{
  QListBox::resizeEvent( event );
  triggerUpdate( true );
}

void Navigator::slotExecuted( QListBoxItem *item )
{
  if ( !item )
    return;

  EntryItem *entry = static_cast<EntryItem*>( item );

  emit pluginActivated( entry->plugin() );
}

IconViewMode Navigator::sizeIntToEnum(int size) const
{
  switch ( size ) {
    case int(LargeIcons):
      return LargeIcons;
      break;
    case int(NormalIcons):
      return NormalIcons;
      break;
    case int(SmallIcons):
      return SmallIcons;
      break;
    case int(TextOnly):
      return TextOnly;
      break;
    default:
      // Stick with sane values
      return NormalIcons;
      kdDebug() << "View mode not implemented!" << endl;
      break;
  }
}

void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint &pos )
{
  KPopupMenu menu;
  menu.insertTitle( i18n( "Icon Size" ) );
  menu.insertItem( i18n( "Large" ), (int)LargeIcons );
  menu.insertItem( i18n( "Normal" ), (int)NormalIcons );
  menu.insertItem( i18n( "Small" ), (int)SmallIcons );
  menu.insertItem( i18n( "Text Only" ), (int)TextOnly );
  int choice = menu.exec( pos );

  if ( choice == -1 )
    return;

  mViewMode = sizeIntToEnum( choice );
  Prefs::self()->setSidePaneIconSize( choice );

  int maxWidth = 0;
  QListBoxItem* it = 0;
  for (int i = 0; (it = item(i)) != 0; ++i)
  {
    int width = it->width(this);
    if (width > maxWidth)
      maxWidth = width;
  }
  parentWidget()->setFixedWidth( maxWidth );

  triggerUpdate( true );
}

void Navigator::shortCutSelected( int pos )
{
  setCurrentItem( pos );
}

IconSidePane::IconSidePane( Core *core, QWidget *parent, const char *name )
  : SidePaneBase( core, parent, name )
{
  mNavigator = new Navigator( this );
  connect( mNavigator, SIGNAL( pluginActivated( Kontact::Plugin* ) ),
           SIGNAL( pluginSelected( Kontact::Plugin* ) ) );

  setAcceptDrops( true );
}

IconSidePane::~IconSidePane()
{
}

void IconSidePane::updatePlugins()
{
  mNavigator->updatePlugins( core()->pluginList() );
}

void IconSidePane::selectPlugin( Kontact::Plugin *plugin )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
    if ( item->plugin() == plugin ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

void IconSidePane::selectPlugin( const QString &name )
{
  bool blocked = signalsBlocked();
  blockSignals( true );

  uint i;
  for ( i = 0; i < mNavigator->count(); ++i ) {
    EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
    if ( item->plugin()->identifier() == name ) {
      mNavigator->setCurrentItem( i );
      break;
    }
  }

  blockSignals( blocked );
}

#include "iconsidepane.moc"

// vim: sw=2 sts=2 et tw=80
<|endoftext|>