Esempio n. 1
0
void totpClient() {
  RTCunadjustedWizard(1);
  if(isRTCunadjusted()) {
    mMsgBoxPush(6);
    multiPrintXY(3, 2, "The OATH TOTP\nauthenticator\ncan't work with\nthe clock\nunadjusted.",
                 TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK);
    closeMsgBox(0, 7);
    return;
  }
  totp ts[MAX_DAY_EVENTS];
  Menu menu;
  menu.type = MENUTYPE_FKEYS;
  MenuItem items[MAX_DAY_EVENTS];
  menu.items = items;
  reload:
  menu.numitems = loadTOTPs(ts);
  for(int i = 0; i < menu.numitems; i++) {
    items[i].text = ts[i].name;
  }
  menu.title = (char*)"TOTP authenticator";
  menu.scrollout = 1;
  menu.height = 7;
  menu.nodatamsg = (char*)"No tokens - press F2";
  menu.returnOnRight = 1;
  while(1) {
    drawFkeyLabels(0, 0x0186, 0, 0, 0, 0x012A); // NEW, TIME
    if(menu.numitems) {
      drawFkeyLabels(0x0235, -1, 0x0188, 0x0038); // FACTOR, RENAME, DELETE
    }
    int res = doMenu(&menu);
    switch(res) {
      case MENU_RETURN_EXIT:
        return;
      case KEY_CTRL_F1:
        if(!menu.numitems) break;
      case MENU_RETURN_SELECTION:
        viewTOTPcode(&ts[menu.selection-1]);
        break;
      case KEY_CTRL_F2:
        if(menu.numitems >= MAX_DAY_EVENTS) {
          AUX_DisplayErrorMessage(0x2E);
        } else {
          if(addTOTPwizard()) goto reload;
        }
        break;
      case KEY_CTRL_F3:
        if(menu.numitems && renameTOTPscreen(menu.selection-1, ts[menu.selection-1].name))
          goto reload;
        break;
      case KEY_CTRL_F4:
      case KEY_CTRL_DEL:
        if(menu.numitems && deleteTOTPprompt(menu.selection-1)) goto reload;
        break;
      case KEY_CTRL_F6:
        setTimezone();
        break;
    }
  }
}
Esempio n. 2
0
int createWalletWizard(int isFirstUse) {
  SetBackGround(0x0A);
  drawScreenTitle("Create wallet", "Name:");
  drawFkeyLabels(0, 0, 0, 0, 0, 0x04A3);
  if(isFirstUse) {
    multiPrintMini(0, 5*24, "To use the balance manager, start by\n"
                            "creating a wallet.");
  }
  char wallet[MAX_WALLETNAME_SIZE+2] = "";
  textInput input;
  input.charlimit=MAX_WALLETNAME_SIZE;
  input.acceptF6=1;
  input.forcetext=1;
  input.symbols = 0;
  input.buffer = (char*)wallet;
  while(1) {
    input.key=0;
    int res = doTextInput(&input);
    if (res==INPUT_RETURN_EXIT) return -1; // user aborted
    else if (res==INPUT_RETURN_CONFIRM) break; // continue to next step
  }

  SetBackGround(0x0A);
  drawScreenTitle("Create wallet", "Initial balance:");
  drawFkeyLabels(-1, -1, -1, -1, -1, 0x04A4);
  char balance[20] = "";
  Currency initialBalance;
  textInput input2;
  input2.charlimit=12;
  input2.acceptF6=1;
  input2.symbols = 0; // allow the decimal separator
  input2.buffer = (char*)balance;
  input2.type = INPUTTYPE_NUMERIC;
  while(1) {
    input2.key=0;
    int res = doTextInput(&input2);
    if (res==INPUT_RETURN_EXIT) return -1; // user aborted
    else if (res==INPUT_RETURN_CONFIRM) {
      if(!stringToCurrency(&initialBalance, balance)) break;
      else AUX_DisplayErrorMessage(0x43);
    }
  }
  createWallet(wallet, &initialBalance);
  if(isFirstUse) {
    char fname[MAX_FILENAME_SIZE];
    walletNameToPath(fname, wallet);
    setCurrentWallet(fname);
  }
  return 0;
}
Esempio n. 3
0
void check_do_graph() {
  if(has_drawn_graph) {
    has_drawn_graph = 0;
    int key;
    int fkeymenu = 0;
    while(1) {
      DisplayStatusArea();
      if(fkeymenu == 1) drawFkeyLabels(0x005F, 0x0060, 0x0061); // INITIAL, TRIG, STANDRD
      GetKey(&key);
      double xmin, xmax, ymin, ymax, xrange, yrange;
      get_xyminmax(&xmin, &xmax, &ymin, &ymax);
      xrange = xmax - xmin;
      yrange = ymax - ymin;
      if(fkeymenu == 0) {
        if(key == KEY_CTRL_LEFT || key == KEY_CTRL_RIGHT) {
          if(key==KEY_CTRL_LEFT) {
            xmin -= xrange * 0.15;
            xmax -= xrange * 0.15;
          } else {
            xmin += xrange * 0.15;
            xmax += xrange * 0.15;
          }
          // easier than having to set the symbols in the complicated eigenmath system:
          static char command[100];
          sprintf(command, "xrange=(%g,%g)", xmin, xmax);
          execution_in_progress = 1;
          has_drawn_graph = 0;
          run(command);
          run(expr);
          execution_in_progress = 0;
        } else if(key == KEY_CTRL_DOWN || key == KEY_CTRL_UP) {
          if(key==KEY_CTRL_DOWN) {
            ymin -= yrange * 0.15;
            ymax -= yrange * 0.15;
          } else {
            ymin += yrange * 0.15;
            ymax += yrange * 0.15;
          }
          // easier than having to set the symbols in the complicated eigenmath system:
          static char command[100];
          sprintf(command, "yrange=(%g,%g)", ymin, ymax);
          execution_in_progress = 1;
          has_drawn_graph = 0;
          run(command);
          run(expr);
          execution_in_progress = 0;
        } else if(key == KEY_CHAR_PLUS || key == KEY_CHAR_MINUS) {
          if(key==KEY_CHAR_PLUS) {
            // 0.75 is 3/4
            xmin = xmin * 0.75;
            xmax = xmax * 0.75;
            ymin = ymin * 0.75;
            ymax = ymax * 0.75;
          } else {
            // 1.(3), or 1/(3/4), or 4/3
            xmin = xmin * 4.0/3.0;
            xmax = xmax * 4.0/3.0;
            ymin = ymin * 4.0/3.0;
            ymax = ymax * 4.0/3.0;
          }
          // easier than having to set the symbols in the complicated eigenmath system:
          static char command[100];
          sprintf(command, "yrange=(%g,%g)", ymin, ymax);
          execution_in_progress = 1;
          run(command);
          sprintf(command, "xrange=(%g,%g)", xmin, xmax);
          has_drawn_graph = 0;
          run(command);
          run(expr);
          execution_in_progress = 0;
        } else if(key == KEY_CTRL_F3) {
          fkeymenu = 1;
          key = 0;
        } else if(key == KEY_CTRL_EXIT || key==KEY_CTRL_F6) break;
      }
      if(fkeymenu == 1) {
        if(key == KEY_CTRL_F1) {
          execution_in_progress = 1;
          run("xrange=(-10,10)");
          run("yrange=(-10,10)");
          has_drawn_graph = 0;
          run(expr);
          execution_in_progress = 0;
        } else if(key == KEY_CTRL_F2) {
          execution_in_progress = 1;
          static char command[100];
          sprintf(command, "xrange=(%g,%g)", -3.0*M_PI, 3.0*M_PI);
          run(command);
          run("yrange=(-1.6, 1.6)");
          has_drawn_graph = 0;
          run(expr);
          execution_in_progress = 0;
        } else if(key == KEY_CTRL_F3) {
          execution_in_progress = 1;
          run("xrange=(-10,10)");
          run("yrange=(-5,5)");
          has_drawn_graph = 0;
          run(expr);
          execution_in_progress = 0;
        } else if(key == KEY_CTRL_EXIT) {
          fkeymenu = 0;
          execution_in_progress = 1;
          has_drawn_graph = 0;
          run(expr);
          execution_in_progress = 0;
        }
      }
    }
  }
}
Esempio n. 4
0
void textfileEditor(char* filename, char* basefolder) {
  int newfile = (filename == NULL);
  char sText[TEXT_BUFFER_SIZE] = "";
  if(!newfile) {
    newfile = 0;
    int openerror = 0;
    int hFile = fileOpen(filename); // Get handle
    if(hFile >= 0) // Check if it opened
    { //opened
      unsigned int filesize = Bfile_GetFileSize_OS(hFile);
      if(!filesize || filesize > TEXT_BUFFER_SIZE) {
        openerror = 1;
      } else {
        Bfile_ReadFile_OS(hFile, sText, TEXT_BUFFER_SIZE, 0);
      }
      Bfile_CloseFile_OS(hFile);
    } else {
      openerror = 1;
    }
    if(openerror) {
      //Error opening file, abort
      AUX_DisplayErrorMessage(0x2B); // Data ERROR
      return;
    }
  }
  textEdit input;
  //input.forcetext=1;
  input.charlimit=TEXT_BUFFER_SIZE;
  input.buffer = (char*)sText;

  // calculate checksum so we can check for changes
  unsigned char origHash[20] = "";
  sha1((unsigned char*)sText, strlen(sText), origHash);
  while(1) {
    input.key=0;
    int res = doTextEdit(&input);
    int exit = 0;
    switch(res) {
      case TEXTEDIT_RETURN_EXIT:
      {
        exit = 1;
        unsigned char newHash[20] = "";
        sha1((unsigned char*)sText, strlen(sText), newHash);
        if(!memcmp(origHash, newHash, 20)) return;
        else {
          mMsgBoxPush(4);
          mPrintXY(3, 2, "Save this file?", TEXT_MODE_TRANSPARENT_BACKGROUND,
                   TEXT_COLOR_BLACK);
          if(closeMsgBox(1, 4)) {
            // fall through
          } else {
            return;
          }
        }
      }
      case TEXTEDIT_RETURN_CONFIRM:
      {
        char newfilename[MAX_FILENAME_SIZE];
        unsigned short newfilenameshort[0x10A];
        if(newfile) {
          int backToEditor = 0;
          SetBackGround(13);
          drawScreenTitle("Text Editor", "Save file as:");
          drawFkeyLabels(0x036F); // <
          textInput ninput;
          ninput.forcetext=1;
          ninput.charlimit=MAX_NAME_SIZE;
          char nfilename[MAX_NAME_SIZE];
          nfilename[0] = 0;
          ninput.buffer = (char*)nfilename;
          while(1) {
            ninput.key = 0;
            int nres = doTextInput(&ninput);
            if (nres==INPUT_RETURN_EXIT || (nres==INPUT_RETURN_KEYCODE && ninput.key==KEY_CTRL_F1)) {
              // user aborted
              backToEditor = 1;
              break;
            } else if (nres==INPUT_RETURN_CONFIRM) {
              if(stringEndsInG3A(nfilename)) {
                mMsgBoxPush(4);
                multiPrintXY(3, 2, "g3a files can't\nbe created by\nan add-in.",
                             TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK);
                closeMsgBox();
              } else {
                // create and save file
                strcpy(newfilename, basefolder);
                strcat(newfilename, nfilename);
                Bfile_StrToName_ncpy(newfilenameshort, newfilename, 0x10A);
                break;
              }
            }
          }
          if(backToEditor) continue;
        } else {
          // delete, then create and save file
          Bfile_StrToName_ncpy(newfilenameshort, filename, 0x10A);
          Bfile_DeleteEntry(newfilenameshort);
        }
        size_t size = strlen(sText);
        if(Bfile_CreateEntry_OS(newfilenameshort, CREATEMODE_FILE, &size) < 0) { //create the file
          // it appears file exists, overwrite?
          if(overwriteFilePrompt(newfilename)) {
            Bfile_DeleteEntry(newfilenameshort);
            Bfile_CreateEntry_OS(newfilenameshort, CREATEMODE_FILE, &size);
          }
          else continue; // abort file save so user can discard the file, or type another filename.
        }
        
        int h = Bfile_OpenFile_OS(newfilenameshort, READWRITE, 0);
        if(h >= 0) { // Still failing?
          //Write file contents
          Bfile_WriteFile_OS(h, sText, size);
          Bfile_CloseFile_OS(h);
          // clear unsaved changes "flag":
          sha1((unsigned char*)sText, strlen(sText), origHash);
        }
        if(exit) return;
      }
      break;
    }
  }
}
Esempio n. 5
0
int addTOTPwizard() {
  char friendlyname[25] = "";
  char key[32] = "";
  int curstep = 0;
  while(1) {
    SetBackGround(0x0A);
    drawScreenTitle("Add TOTP token");
    // < (first label) and Next or Finish (last label)
    drawFkeyLabels((curstep>0 ? 0x036F : 0), 0, 0, 0, 0, (curstep==1 ? 0x04A4 : 0x04A3));
    if(curstep == 0) {
      drawScreenTitle(NULL, "Friendly name:");
      textInput input;
      input.charlimit=21;
      input.acceptF6=1;
      input.forcetext = 1;
      input.buffer = friendlyname;
      while(1) {
        input.key=0;
        int res = doTextInput(&input);
        if (res==INPUT_RETURN_EXIT) return 0; // user aborted
        else if (res==INPUT_RETURN_CONFIRM) {
          curstep++;
          break;
        }
      }
    } else if(curstep == 1) {
      drawScreenTitle(NULL, "Base32 key:");
      multiPrintMini(0, 3*24+2, "This is often shown as a QR code.\n"
                                "Try looking for the \"I can't scan a QR\n"
                                "code\" option. A key usually looks\n"
                                "like this: JBSWY3DPEHPK3PXP\n"
                                "Some keys are longer.");
      textInput input;
      input.charlimit=32;
      input.acceptF6=1;
      input.symbols = 0;
      input.forcetext = 1;
      input.buffer = key;
      int inloop = 1;
      while(inloop) {
        input.key=0;
        int res = doTextInput(&input);
        if (res==INPUT_RETURN_EXIT) return 0; // user aborted
        else if (res==INPUT_RETURN_CONFIRM) {
          char* b = key;
          for(; *b; b++) {
            *b = toupper(*b);
            // commonly mistyped characters:
            if(*b == '0') *b = 'O';
            if(*b == '1') *b = 'I';
          }
          if(base32_validate(key)) {
            inloop = 0; // all fields complete, continue with token adding
          } else {
            AUX_DisplayErrorMessage(0x3E);
          }
        }
        else if (res==INPUT_RETURN_KEYCODE && input.key == KEY_CTRL_F1) {
          curstep--;
          break;
        }
      }
      if(!inloop) break;
    }
  }
  addTOTP(friendlyname, key);
  return 1;
}
Esempio n. 6
0
int balanceManagerChild(Menu* menu, char* currentWallet) {
  Currency balance;
  getWalletBalance(&balance, currentWallet);
  char balanceStr[15];
  currencyToString(balanceStr, &balance);
  char subtitle[21];
  strcpy(subtitle, (char*)"Balance: ");
  strcat(subtitle, balanceStr);
  Transaction txs[MAX_DAY_EVENTS];
  char menulabels[MAX_DAY_EVENTS][44];
  menu->numitems = getWalletTransactions(currentWallet, txs);
  MenuItem items[menu->numitems];
  for(int i = 0; i < menu->numitems; i++) {
    char amount[15];
    currencyToString(amount, &txs[i].amount);

    // build menu item so that the text is cut and the values aligned on the right column
    // independently of the description containing multibyte chars and their location
    char* s = txs[i].description;
    int len = 0, glen = 0;
    while(*s) {
      len++;
      glen++;
      if(MB_IsLead(*s)) glen--;
      if(glen >= 14) { // this way we only care about the section that is to be displayed
        break;
      }
      s++;
    }
    memset(menulabels[i], ' ', 43); // blank parts that would not be touched
    int offset = len-glen;
    memcpy(menulabels[i], txs[i].description, (glen > 14 ? 14+offset : len));
    if(MB_IsLead(menulabels[i][14+offset]))
      menulabels[i][14+offset] = ' '; // eliminate half-MB char
    strncpy(menulabels[i]+15+offset, amount, 6);
    menulabels[i][21+offset] = 0;

    if(txs[i].credit) items[i].color = TEXT_COLOR_GREEN;
    else items[i].color = TEXT_COLOR_RED;
    items[i].text = menulabels[i];
  }
  menu->items = items;
  while(1) {
    Bdisp_AllClr_VRAM();
    drawScreenTitle("Balance Manager", subtitle);
    // VIEW, INSERT, EDIT, DELETE, empty, LOAD
    drawFkeyLabels(-1, 0x03B4, -1, -1, -1, 0x03B7);
    if(menu->numitems > 0) drawFkeyLabels(0x049F, -1, 0x0038);
    int res = doMenu(menu);
    switch(res) {
      case MENU_RETURN_EXIT:
        return 0;
        break;
      case KEY_CTRL_F1:
      case MENU_RETURN_SELECTION:
        if(menu->numitems) viewTransaction(&txs[menu->selection-1]);
        break;
      case KEY_CTRL_F2:
        if(addTransactionWizard(currentWallet)) {
          return 1;
        }
        break;
      case KEY_CTRL_F3:
      case KEY_CTRL_DEL:
        if(menu->numitems &&
           deleteTransactionPrompt(txs, currentWallet, menu->numitems, menu->selection-1)) {
          return 1;
        }
        break;
      case KEY_CTRL_F6:
        if(changeWalletScreen(currentWallet)) {
          menu->selection = 0;
          menu->scroll = 0;
          return 1;
        }
        break;
    }
  }
  return 0;
}
Esempio n. 7
0
void passwordGenerator() {
  Menu menu;
  menu.type = MENUTYPE_FKEYS;
  menu.title = (char*)"Password Generator";
  menu.height = 7;
  MenuItem items[6];
  int length = 10;
  int seed = RTC_GetTicks() * (GetMainBatteryVoltage(1) % 100);
  char lstr[10];
  items[1].text = (char*)"Include symbols";
  items[1].type = MENUITEM_CHECKBOX;
  items[2].text = (char*)"Include numbers";
  items[2].type = MENUITEM_CHECKBOX;
  items[2].value = MENUITEM_VALUE_CHECKED;
  items[3].text = (char*)"Include uppercase";
  items[3].type = MENUITEM_CHECKBOX;
  items[3].value = MENUITEM_VALUE_CHECKED;
  items[4].text = (char*)"Include confusable";
  items[4].type = MENUITEM_CHECKBOX;
  items[4].value = MENUITEM_VALUE_CHECKED;
  items[5].text = (char*)"Memorable vowel mix";
  items[5].type = MENUITEM_CHECKBOX;
  menu.numitems = 6;
  menu.items = items;
  while(1) {
    drawFkeyLabels(0x03B3, 0, 0, 0, 0, 0x0184); // FILE, EXE (white)
    itoa(length, (unsigned char*)lstr);
    char t[20];
    strcpy(t, "Length: ");
    strcat(t, lstr);
    items[0].text = t;
    switch(doMenu(&menu)) {
      case MENU_RETURN_EXIT:
        return;
      case MENU_RETURN_SELECTION:
        if(menu.selection > 1) items[menu.selection-1].value = !items[menu.selection-1].value;
        else {
          Selector sel;
          sel.min = 6;
          sel.value = length;
          sel.max = 30;
          sel.cycle = 1;
          sel.title = (char*)"Password Generator";
          sel.subtitle = (char*)"Length";
          if(doSelector(&sel) == SELECTOR_RETURN_SELECTION) {
            length = sel.value;
          }
        }
        break;
      case KEY_CTRL_F1:
      {
        Selector sel;
        sel.min = 1;
        sel.value = 10;
        sel.max = 1000;
        sel.cycle = 1;
        sel.title = (char*)"Generate to file";
        sel.subtitle = (char*)"Number of passwords";
        if(doSelector(&sel) != SELECTOR_RETURN_SELECTION) break;

        SetBackGround(10);
        drawScreenTitle("Generate to file", "Filename:");
        char newname[MAX_NAME_SIZE];
        newname[0] = 0;
        textInput input;
        input.forcetext=1;
        input.symbols = 0;
        input.charlimit=MAX_NAME_SIZE;
        input.buffer = (char*)newname;
        int inscreen = 1;
        while(inscreen) {
          input.key=0;
          int res = doTextInput(&input);
          if (res==INPUT_RETURN_EXIT) break; // user aborted
          else if (res==INPUT_RETURN_CONFIRM) {
            inscreen = 0;
          }
        }
        if(inscreen) break;
        char newfilename[MAX_FILENAME_SIZE];
        strcpy(newfilename, SMEM_PREFIX);
        strcat(newfilename, newname);
        strcat(newfilename, ".txt");
        unsigned short pFile[0x10A];
        Bfile_StrToName_ncpy(pFile, newfilename, 0x10A);
        unsigned int size = 1;
        int ntry = 0;
        while(ntry < 2) {
          ntry++;
          int BCEres = Bfile_CreateEntry_OS(pFile, CREATEMODE_FILE, &size);
          if(BCEres >= 0) {
            int hFile = Bfile_OpenFile_OS(pFile, READWRITE, 0); // Get handle
            if(hFile >= 0) {
              char password[35];
              char line[37];
              for(int i = 0; i < sel.value; i++) {
                generateRandomString(password, length, items[1].value, items[2].value,
                                     items[3].value, items[4].value, items[5].value, &seed);
                sprintf(line, "%s\r\n", password);
                Bfile_WriteFile_OS(hFile, line, length+2);
              }
              Bfile_CloseFile_OS(hFile);
            } else AUX_DisplayErrorMessage(0x2B);
            break;
          } else if(ntry < 2) {
            // File creation probably failed due to the presence of a file with the same name
            if(overwriteFilePrompt(newfilename))
              Bfile_DeleteEntry(pFile);
            else
              break;
          } else AUX_DisplayErrorMessage(0x2B);
        }
        break;
      }
      case KEY_CTRL_F6:
        int inscreen = 1;
        while(inscreen) {
          Bdisp_AllClr_VRAM();
          drawScreenTitle("Password Generator", "Generated passwords:");
          textArea text;
          text.type = TEXTAREATYPE_INSTANT_RETURN;
          text.scrollbar = 0;
          text.y = 48+3;
          text.lineHeight = 20;
          textElement e[5];
          char passwords[5][35];
          for(int i = 0; i < 5; i++) {
            generateRandomString(passwords[i], length, items[1].value, items[2].value,
                                 items[3].value, items[4].value, items[5].value, &seed);
            e[i].text = passwords[i];
            if(i) e[i].newLine = 1;
          }
          text.elements = e;
          text.numelements = 5;
          doTextArea(&text);
          drawFkeyLabels(0x036F, 0, 0, 0, 0, 0x02B9); // <, REPEAT (white)
          while(1) {
            int key;
            mGetKey(&key);
            if(key == KEY_CTRL_F6) break;
            if(key == KEY_CTRL_F1 || key == KEY_CTRL_EXIT) {
              inscreen = 0;
              break;
            }
          }
        }
        break;
    }
  }
}
Esempio n. 8
0
int changeWalletScreen(char* currentWallet) {
  // returns 1 if user changes to another wallet
  char* currentWalletNice = filenameToName(currentWallet);
  Menu menu;
  menu.title = (char*)"Wallet List";
  menu.scrollout=1;
  menu.type=MENUTYPE_FKEYS;
  menu.height = 7;
  MenuItem items[MAX_WALLETS];
  int mustRefresh = 0;
  while(1) {
    char wallets[MAX_WALLETS][MAX_WALLETNAME_SIZE];
    // build wallet list:
    unsigned short path[MAX_FILENAME_SIZE+1], found[MAX_FILENAME_SIZE+1];
    char buffer[MAX_FILENAME_SIZE+1];

    // make the buffer
    strcpy(buffer, BALANCEFOLDER"\\*");
    
    file_type_t fileinfo;
    int findhandle;
    Bfile_StrToName_ncpy(path, buffer, MAX_FILENAME_SIZE+1);
    int ret = Bfile_FindFirst_NON_SMEM((const char*)path, &findhandle, (char*)found, &fileinfo);
    int i = 0;
    while(!ret) {
      Bfile_NameToStr_ncpy(buffer, found, MAX_FILENAME_SIZE+1);
      if(fileinfo.fsize == 0 &&
         !(strcmp((char*)buffer, "..") == 0 || strcmp((char*)buffer, ".") == 0)) { // find folders
        strcpy(wallets[i], buffer);
        items[i].text = wallets[i];
        i++;
        if(!strcmp(buffer, currentWalletNice)) menu.selection = i;
        if(i == MAX_WALLETS) break;
      }
      ret = Bfile_FindNext_NON_SMEM(findhandle, (char*)found, (char*)&fileinfo);
    }
    menu.items = items;
    menu.numitems = i;
    Bfile_FindClose(findhandle);
    drawFkeyLabels(0x000F, 0x0186, 0x0188, 0x0038, 0, 0); // SELECT, NEW, RENAME, DELETE
    int res = doMenu(&menu);
    switch(res) {
      case MENU_RETURN_EXIT:
        return mustRefresh;
        break;
      case KEY_CTRL_F1:
      case MENU_RETURN_SELECTION:
        if(strcmp(currentWalletNice, wallets[menu.selection-1])) {
          walletNameToPath(buffer, wallets[menu.selection-1]);
          setCurrentWallet(buffer);
          return 1;
        } return mustRefresh;
        break;
      case KEY_CTRL_F2:
        if(menu.numitems >= MAX_WALLETS) {
          AUX_DisplayErrorMessage( 0x2E );
        } else {
          createWalletWizard(0);
        }
        break;
      case KEY_CTRL_F3:
        char newWallet[MAX_FILENAME_SIZE];
        if(renameWalletScreen(wallets[menu.selection-1], newWallet)) {
          walletNameToPath(buffer, wallets[menu.selection-1]);
          if(!strcmp(currentWallet, buffer)) {
            // if the renamed wallet was the current one, we must set the current wallet to the
            // new name.
            setCurrentWallet(newWallet);
            mustRefresh = 1;
          }
        }
        break;
      case KEY_CTRL_F4:
      case KEY_CTRL_DEL:
        walletNameToPath(buffer, wallets[menu.selection-1]);
        if(deleteWalletPrompt(buffer)) {
          if(menu.numitems <= 1) {
            // this was the only wallet: delete pointer file too, so that user is prompted to create
            // a new wallet.
            unsigned short path[MAX_FILENAME_SIZE+1];
            strcpy(buffer, BALANCEFOLDER"\\Wallet");
            Bfile_StrToName_ncpy(path, buffer, MAX_FILENAME_SIZE);
            Bfile_DeleteEntry(path);
            return 1;
          }
          if(!strcmp(currentWallet, buffer)) {
            // if the deleted wallet was the current one, we must set the current wallet to the
            // first one on the list that is not the deleted one.
            // (by now we know there is more than one wallet in the list)
            for(int i = 0; i < menu.numitems; i++) {
              walletNameToPath(buffer, wallets[i]);
              if(strcmp(currentWallet, buffer)) break;
            }
            setCurrentWallet(buffer);
            mustRefresh = 1;
          }
        }
        break;
    }
  }
}
Esempio n. 9
0
int addTransactionWizard(char* wallet) {
  Transaction tx;
  tx.date.year = getCurrentYear();
  tx.date.month = getCurrentMonth();
  tx.date.day = getCurrentDay();
  tx.time.hour = getCurrentHour();
  tx.time.minute = getCurrentMinute();
  tx.time.second = getCurrentSecond();
  strcpy(tx.description, (char*)"");
  int curstep = 0;
  while(1) {
    SetBackGround(0x0A);
    drawScreenTitle("Add transaction");
    // < (first label), SELECT of on date step, and Next or Finish (last label)
    drawFkeyLabels(curstep>0 ? 0x036F : -1, curstep == 2 ? 0x000F : 0, 0, 0, 0,
                   curstep==4 ? 0x04A4 : 0x04A3);
    if(curstep == 0) {
      MenuItem menuitems[5];
      menuitems[0].text = (char*)"Debit";
      menuitems[1].text = (char*)"Credit";

      Menu menu;
      menu.items=menuitems;
      menu.type=MENUTYPE_FKEYS;
      menu.numitems=2;
      menu.height=2;
      menu.startY=3;
      menu.pBaRtR=1;
      int inloop=1;
      while(inloop) {
        // this must be here, inside this loop:
        SetBackGround(0x0A);
        drawScreenTitle("Add transaction", "Select type:");
        drawFkeyLabels(-1, -1, -1, -1, -1, 0x04A3);
        int res = doMenu(&menu);
        if(res == MENU_RETURN_EXIT) return 0;
        else if(res == KEY_CTRL_F6 || res == MENU_RETURN_SELECTION) {
          tx.credit = menu.selection == 2;
          curstep++;
          break;
        }
      }
    } else if(curstep == 1) {
      drawScreenTitle(NULL, "Amount:");
      char samount[20] = "";
      if(tx.amount.val) {
        currencyToString(samount, &tx.amount);
      }
      textInput input;
      input.charlimit=12;
      input.acceptF6=1;
      input.symbols = 0; // allow the decimal separator
      input.forcetext = 1;
      input.buffer = (char*)samount;
      input.type = INPUTTYPE_NUMERIC;
      while(1) {
        input.key=0;
        int res = doTextInput(&input);
        if (res==INPUT_RETURN_EXIT) return 0; // user aborted
        else if (res==INPUT_RETURN_CONFIRM) {
          if(!stringToCurrency(&tx.amount, samount)) {
            if(!tx.amount.val) {
              AUX_DisplayErrorMessage(0x4B);
            } else {
              curstep++;
            }
            break;
          } else AUX_DisplayErrorMessage(0x43);
        } else if (res==INPUT_RETURN_KEYCODE && input.key == KEY_CTRL_F1) {
          curstep--;
          break;
        }
      }
    } else if(curstep == 2) {
      drawScreenTitle(NULL, "Date:");
      mPrintXY(7, 4, getInputDateFormatHint(), TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK);
      textInput input;
      input.x=7;
      input.width=8;
      input.charlimit=8;
      input.acceptF6=1;
      input.type=INPUTTYPE_DATE;
      char datebuffer[15];
      fillInputDate(&tx.date, datebuffer);
      input.buffer = (char*)datebuffer;
      while(1) {
        input.key=0;
        int res = doTextInput(&input);
        if (res==INPUT_RETURN_EXIT) return 0; // user aborted
        else if (res==INPUT_RETURN_CONFIRM) {
          int len = strlen(datebuffer);
          if(len == input.charlimit) {
            int yr,m,d;
            stringToDate(datebuffer, &yr, &m, &d);
            if(isDateValid(yr, m, d)) {
                tx.date.year = yr;
                tx.date.month = m;
                tx.date.day = d;
                curstep++;
                break; // continue to next step
            } else invalidFieldMsg(0);
          } else invalidFieldMsg(0);
        } else if (res==INPUT_RETURN_KEYCODE) {
          if(input.key==KEY_CTRL_F1) {
            curstep=curstep-1; break;
          } else if(input.key==KEY_CTRL_F2) {
            int ey=0, em=0, ed=0;
            if(!selectDateScreen(&ey, &em, &ed,
                                  (char*)"Select transaction date:", NULL, 1)) {
              tx.date.year = ey;
              tx.date.month = em;
              tx.date.day = ed;
              curstep++; break; // continue to next step
            }
            break; //redraw
          }
        }
      }
    } else if(curstep == 3) {
      drawScreenTitle(NULL, "Time:");
      mPrintXY(8, 4, "HHMMSS", TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK);
      
      textInput input;
      input.x=8;
      input.width=6;
      input.charlimit=6;
      input.acceptF6=1;
      input.type=INPUTTYPE_TIME;
      char tbuffer[15];
      fillInputTime(&tx.time, tbuffer);
      input.buffer = (char*)tbuffer;
      while(1) {
        input.key=0;
        int res = doTextInput(&input);
        if (res==INPUT_RETURN_EXIT) return 0; // user aborted
        else if (res==INPUT_RETURN_CONFIRM) {
          if((int)strlen(tbuffer) == input.charlimit) {
            int h, m, s;
            stringToTime(tbuffer, &h, &m, &s);
            if(isTimeValid(h, m, s)) {
              tx.time.hour = h;
              tx.time.minute = m;
              tx.time.second = s;
              curstep++;
              break; // continue to next step
            } else invalidFieldMsg(1);
          } else invalidFieldMsg(1);
        } 
        else if (res==INPUT_RETURN_KEYCODE && input.key==KEY_CTRL_F1) { curstep--; break; }
      }
    } else if(curstep == 4) {
      drawScreenTitle(NULL, "Description:");
      textInput input;
      input.charlimit=128;
      input.acceptF6=1;
      input.buffer = (char*)tx.description;
      int inloop = 1;
      while(inloop) {
        input.key=0;
        int res = doTextInput(&input);
        if (res==INPUT_RETURN_EXIT)
          return 0; // user aborted
        else if (res==INPUT_RETURN_CONFIRM)
          inloop = 0; // all fields complete, continue with transaction adding
        else if (res==INPUT_RETURN_KEYCODE && input.key == KEY_CTRL_F1) {
          curstep--;
          break;
        }
      }
      if(!inloop) break;
    }
  }
  addTransaction(&tx, wallet);
  return 1;
}
Esempio n. 10
0
int fileBrowserSub(char* browserbasepath, char* filename, char* filter, char* filter2, char* title) {
  Menu menu;
  MenuItemIcon icontable[12];
  buildIconTable(icontable);
  
  // first get file count so we know how much to alloc
  GetFiles(NULL, NULL, browserbasepath, &menu.numitems, filter, filter2);
  MenuItem* menuitems = NULL;
  File* files = NULL;
  if(menu.numitems > 0) {
    menuitems = (MenuItem*)alloca(menu.numitems*sizeof(MenuItem));
    files = (File*)alloca(menu.numitems*sizeof(File));
    // populate arrays
    GetFiles(files, menuitems, browserbasepath, &menu.numitems, filter, filter2);
    menu.items = menuitems;
  }
  
  char titleBuffer[120];
  char titleBufferBuf[120];
  int smemfree;
  unsigned short smemMedia[10]={'\\','\\','f','l','s','0',0};
  Bfile_GetMediaFree_OS( smemMedia, &smemfree );
  
  char friendlypath[MAX_FILENAME_SIZE];
  strcpy(friendlypath, browserbasepath+6);
  friendlypath[strlen(friendlypath)-1] = '\0'; //remove ending slash like OS does
  // test to see if friendlypath is too big
  int jump4=0;
  while(1) {
    int temptextX=7*18+10; // px length of menu title + 10, like menuGUI goes.
    int temptextY=0;
    PrintMini(&temptextX, &temptextY, (char*)friendlypath, 0, 0xFFFFFFFF, 0, 0, COLOR_BLACK, COLOR_WHITE, 0, 0); // fake draw
    if(temptextX>LCD_WIDTH_PX-6) {
      char newfriendlypath[MAX_FILENAME_SIZE];
      shortenDisplayPath(friendlypath, newfriendlypath, (jump4 ? 4 : 1));
      if(strlen(friendlypath) > strlen(newfriendlypath) && strlen(newfriendlypath) > 3) { // check if len > 3 because shortenDisplayPath may return just "..." when the folder name is too big
        // shortenDisplayPath still managed to shorten, copy and continue
        jump4 = 1; //it has been shortened already, so next time jump the first four characters
        strcpy(friendlypath, newfriendlypath);
      } else {
        // shortenDisplayPath can't shorten any more even if it still
        // doesn't fit in the screen, so give up.
        break;
      }
    } else break;
  }
  menu.subtitle = friendlypath;
  menu.type = MENUTYPE_MULTISELECT;
  menu.scrollout=1;
  menu.nodatamsg = (char*)"No Data";
  menu.title = title;
  menu.height=7;
  while(1) {
    Bdisp_AllClr_VRAM();
    drawFkeyLabels((menu.numitems ? 0x03B1 : 0), -1, -1, -1, -1, 0x03DF); // OPEN, VERSION
    itoa(smemfree, (unsigned char*)titleBuffer);
    LocalizeMessage1( 340, titleBufferBuf ); //"bytes free"
    strncat((char*)titleBuffer, (char*)titleBufferBuf, 65);
    menu.statusText = (char*)titleBuffer;
    int res = doMenu(&menu, icontable);
    switch(res) {
      case MENU_RETURN_EXIT:
        if(!strcmp(browserbasepath,"\\\\fls0\\")) { //check that we aren't already in the root folder
          //we are, return 0 so we exit
          //return 0; // in this add-in, the file browser shouldn't return
        } else {
          int i=strlen(browserbasepath)-2;
          while (i>=0 && browserbasepath[i] != '\\')
                  i--;
          if (browserbasepath[i] == '\\') {
            char tmp[MAX_FILENAME_SIZE] = "";
            memcpy(tmp,browserbasepath,i+1);
            tmp[i+1] = '\0';
            strcpy(browserbasepath, tmp);
          }
          return 1; //reload at new folder
        }
        break;
      case KEY_CTRL_F1:
      case MENU_RETURN_SELECTION:
        if(!menu.numitems) break;
        if(menuitems[menu.selection-1].isfolder) {
          strcpy(browserbasepath, files[menu.selection-1].filename); //switch to selected folder
          strcat(browserbasepath, "\\");
          return 1; //reload at new folder
        } else {
          strcpy(filename,files[menu.selection-1].filename);
          return 2;
        }
        break;
      case KEY_CTRL_F6:
        showAbout();
        break;
    }
  }
  return 1;
}
Esempio n. 11
0
int doTextInput(textInput* input) {
  if(input->type==INPUTTYPE_NORMAL) {
    drawFkeyLabels(-1, -1, -1, (input->symbols? 0x02A1 : -1), 0x0307); // CHAR, A<>a
  }
  int wasInClip=0;
  if (input->key)
    input->cursor = EditMBStringChar((unsigned char*)input->buffer, input->charlimit, input->cursor,
                                     input->key);
  int widthForSyscalls = input->width;
  if(input->width == 21) {
    widthForSyscalls = 20;
    clearLine(1, input->y); // remove aestethically unpleasing bit of background at the end of the field
  }
  while(1) {
    if(input->forcetext && strlen(input->buffer)==0) {
      input->buffer[0]='\xd8';
      input->buffer[1]='\x0';
    }
    DisplayMBString2(0, (unsigned char*)input->buffer, input->start, input->cursor, 0, input->x,
                     input->y*24-24, widthForSyscalls+input->x, input->width==21? 0 : 1);
    
    drawLine(input->x*18-18, input->y*24-1,
             input->width == 21 ? LCD_WIDTH_PX-1 : input->width*18+input->x*18-18-1,
             input->y*24-1, COLOR_GRAY);
    drawLine(input->x*18-18, input->y*24+23,
             input->width == 21 ? LCD_WIDTH_PX-1 : input->width*18+input->x*18-18-1,
             input->y*24+23, COLOR_GRAY);
    if(input->width != 21) {
      //vertical lines, start and end
      drawLine(input->x*18-18, input->y*24-1, input->x*18-18, input->y*24+23, COLOR_GRAY);
      drawLine((input->x*18-18)+18*input->width,
               input->y*24-1, (input->x*18-18)+18*input->width, input->y*24+23, COLOR_GRAY);
    }
    if(input->type==INPUTTYPE_DATE) {
      //vertical lines: dd, mm and yyyy separators
      switch(getSetting(SETTING_DATEFORMAT)) {
        case 0:
        case 1:
          drawLine((input->x*18-18)+18*2, input->y*24-1,
                   (input->x*18-18)+18*2, input->y*24+22, COLOR_GRAY);
          drawLine((input->x*18-18)+18*4+1, input->y*24-1,
                   (input->x*18-18)+18*4+1, input->y*24+23, COLOR_GRAY);
          break;
        case 2:
          drawLine((input->x*18-18)+18*4, input->y*24-1,
                   (input->x*18-18)+18*4, input->y*24+22, COLOR_GRAY);
          drawLine((input->x*18-18)+18*6+1, input->y*24-1,
                   (input->x*18-18)+18*6+1, input->y*24+23, COLOR_GRAY);
          break;
      }
    } else if(input->type==INPUTTYPE_TIME) {
      //vertical lines: hh, mm and ss separators
      drawLine((input->x*18-18)+18*2, input->y*24-1,
               (input->x*18-18)+18*2, input->y*24+23, COLOR_GRAY);
      drawLine((input->x*18-18)+18*4, input->y*24-1,
               (input->x*18-18)+18*4, input->y*24+23, COLOR_GRAY);
    }
    int keyflag = GetSetupSetting( (unsigned int)0x14);
    if(input->type==INPUTTYPE_NORMAL) {
      if(keyflag == 0x02) {
        // in clip mode
        wasInClip=1;
        drawFkeyLabels(0x0034, 0x0069); // COPY (white), CUT (white)
      } else if(wasInClip) {
        // clear, because we were in clip mode before
        wasInClip=0;
        drawFkeyLabels(0,0); // empty first two
      }
    }
    mGetKey(&input->key);
    if (GetSetupSetting((unsigned int)0x14) == 0x01 ||
        GetSetupSetting((unsigned int)0x14) == 0x04 ||
        GetSetupSetting( (unsigned int)0x14) == 0x84) {
      keyflag = GetSetupSetting( (unsigned int)0x14); // make sure the flag we're using is the
      // updated one. we can't update always because that way alpha-not-lock will cancel when F5 is
      // pressed.
    }
    if(input->key == KEY_CTRL_EXE || (input->key == KEY_CTRL_F6 && input->acceptF6)) {
      // Next step
      if(!input->forcetext || (strlen((char*)input->buffer) > 0 && input->buffer[0]!='\xd8')) {
        // input can be empty, or it already has some text
        Cursor_SetFlashOff(); return INPUT_RETURN_CONFIRM;
      } else {
        mMsgBoxPush(4);
        multiPrintXY(3, 2, "Field can't be\nleft blank.",
                     TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK);
        closeMsgBox();
      }
    } else if(input->key == KEY_CTRL_EXIT) {
      // Aborted
      Cursor_SetFlashOff(); return INPUT_RETURN_EXIT;
    } else if(input->key == KEY_CTRL_F1 || input->key == KEY_CTRL_F2) {  
      Cursor_SetFlashOff(); return INPUT_RETURN_KEYCODE;
    } else if(input->key == KEY_CTRL_F4 && input->type == INPUTTYPE_NORMAL && input->symbols) {
      short character = selectCharacterAux();
      if (character)
        input->cursor = EditMBStringChar((unsigned char*)input->buffer, input->charlimit,
                                         input->cursor, character);
    } else if(input->key == KEY_CTRL_F5 && input->type == INPUTTYPE_NORMAL) {
      // switch between lower and upper-case alpha
      switch(keyflag) {
        case 0x08:
        case 0x88:
          SetSetupSetting((unsigned int)0x14, keyflag-0x04);
          continue; //do not process the key, because otherwise we will leave alpha status
        case 0x04:
        case 0x84:
          SetSetupSetting((unsigned int)0x14, keyflag+0x04);
          continue; //do not process the key, because otherwise we will leave alpha status
      }
    } 
    if(input->key && input->key < 30000) {
      if(input->type == INPUTTYPE_NORMAL ||
         (input->key >= KEY_CHAR_0 && input->key <= KEY_CHAR_9) ||
         (input->key == KEY_CHAR_DP && !input->symbols && input->type == INPUTTYPE_NUMERIC)) {
        // either a normal input, or only allow digits and eventually the decimal separator
        if ((GetSetupSetting((unsigned int)0x14) == 0x08 ||
             GetSetupSetting((unsigned int)0x14) == 0x88) &&
            input->key >= KEY_CHAR_A && input->key <= KEY_CHAR_Z) //if lowercase and key is char...
          input->key = input->key + 32; // to switch to lower-case characters

        input->cursor = EditMBStringChar((unsigned char*)input->buffer, input->charlimit,
                                         input->cursor, input->key);
      }
    } else EditMBStringCtrl2((unsigned char*)input->buffer, input->charlimit+1, &input->start,
                             &input->cursor, &input->key, input->x, input->y*24-24, 1,
                             widthForSyscalls+input->x-1 );
    if(input->key == KEY_CTRL_PASTE) {
      // at this point it will have already pasted
      int pos = strlen(input->buffer)-1;
      if(input->forcetext && pos > 0 && input->buffer[pos]=='\xd8') {
        input->buffer[pos]='\x0';
      }
    }
  }
  Cursor_SetFlashOff();
  return INPUT_RETURN_CONFIRM;
}