Exemplo n.º 1
0
int WDL_CursesEditor::init(const char *fn, const char *init_if_empty)
{
  m_filename.Set(fn);
  FILE *fh=fopenUTF8(fn,"rt");

  if (!fh) 
  {
    if (init_if_empty)
    {
      fh=fopenUTF8(fn,"w+t");
      if (fh)
      {
        fwrite(init_if_empty,1,strlen(init_if_empty),fh);

        fseek(fh,0,SEEK_SET);
      }
    }
    if (!fh)
    {
      saveUndoState();
      m_clean_undopos=m_undoStack_pos;
      return 1;
    }
  }
  while(!feof(fh))
  {
    char line[4096];
    line[0]=0;
    fgets(line,sizeof(line),fh);
    if (!line[0]) break;

    int l=strlen(line);
    while(l>0 && (line[l-1]=='\r' || line[l-1]=='\n'))
    {
      line[l-1]=0;
      l--;
    }
    WDL_FastString *str=new WDL_FastString;
    char *p=line,*np;
    while ((np=strstr(p,"\t"))) // this should be optional, perhaps
    {
      *np=0;
      str->Append(p);
      { int x; for(x=0;x<m_indent_size;x++) str->Append(" "); }
      p=np+1;
    }
    if (p) str->Append(p);
    m_text.Add(str);
  }
  fclose(fh);
  saveUndoState();
  m_clean_undopos=m_undoStack_pos;

  return 0;
}
void GuiTextEditCtrl::onCopy(bool andCut)
{
   // Don't copy/cut password field!
   if(mPasswordText)
      return;

   if (mBlockEnd > 0)
   {
      //save the current state
      saveUndoState();

      //copy the text to the clipboard
      UTF8* clipBuff = mTextBuffer.createSubstring8(mBlockStart, mBlockEnd - mBlockStart);
      Platform::setClipboard(clipBuff);
      delete[] clipBuff;

      //if we pressed the cut shortcut, we need to cut the selected text from the control...
      if (andCut)
      {
         mTextBuffer.cut(mBlockStart, mBlockEnd - mBlockStart);
         mCursorPos = mBlockStart;
      }

      mBlockStart = 0;
      mBlockEnd = 0;
   }

}
void GuiTextEditCtrl::onPaste()
{           
   //first, make sure there's something in the clipboard to copy...
   const UTF8 *clipboard = Platform::getClipboard();
   if(dStrlen(clipboard) <= 0)
      return;

   //save the current state
   saveUndoState();

   //delete anything hilited
   if (mBlockEnd > 0)
   {
      mTextBuffer.cut(mBlockStart, mBlockEnd - mBlockStart);
      mCursorPos = mBlockStart;
      mBlockStart = 0;
      mBlockEnd = 0;
   }

   // We'll be converting to UTF16, and maybe trimming the string,
   // so let's use a StringBuffer, for convinience.
   StringBuffer pasteText(clipboard);

   // Space left after we remove the highlighted text
   S32 stringLen = mTextBuffer.length();

   // Trim down to fit in a buffer of size mMaxStrLen
   S32 pasteLen = pasteText.length();

   if(stringLen + pasteLen > mMaxStrLen)
   {
      pasteLen = mMaxStrLen - stringLen;

      pasteText.cut(pasteLen, pasteText.length() - pasteLen);
   }

   if (mCursorPos == stringLen)
   {
      mTextBuffer.append(pasteText);
   }
   else
   {
      mTextBuffer.insert(mCursorPos, pasteText);
   }

   mCursorPos += pasteLen;
}
Exemplo n.º 4
0
void DiagramScene::setLineColor(const QColor &color)
{
    myLineColor = color;

    //Lists of items
    QList<Arrow *> Arrows;
    QList<lineItem *> lineItems;
    foreach(QGraphicsItem *item, selectedItems()){
        if(item->type() == lineItem::Type)
            lineItems.append(qgraphicsitem_cast<lineItem *>(item));
        else if(item->type() == Arrow::Type)
            Arrows.append(qgraphicsitem_cast<Arrow *>(item));
    }

    foreach(Arrow *arrow, Arrows){
        saveUndoState();
        arrow->setColor(myLineColor);
    }
bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event)
{
   if ( !isActive() || !isAwake() )
      return false;

   S32 stringLen = mTextBuffer.length();
   setUpdate();

   // Ugly, but now I'm cool like MarkF.
   if(event.keyCode == KEY_BACKSPACE)
      goto dealWithBackspace;
   
   if ( event.modifier & SI_SHIFT )
   {

      // Added support for word jump selection.

      if ( event.modifier & SI_CTRL )
      {
         switch ( event.keyCode )
         {
            case KEY_LEFT:
            {
               S32 newpos = findPrevWord();               

               if ( mBlockStart == mBlockEnd )
               {
                  // There was not already a selection so start a new one.
                  mBlockStart = newpos;
                  mBlockEnd = mCursorPos;
               }
               else
               {
                  // There was a selection already...
                  // In this case the cursor MUST be at either the
                  // start or end of that selection.

                  if ( mCursorPos == mBlockStart )
                  {
                     // We are at the start block and traveling left so
                     // just extend the start block farther left.                     
                     mBlockStart = newpos;
                  }
                  else
                  {
                     // We are at the end block BUT traveling left
                     // back towards the start block...

                     if ( newpos > mBlockStart )
                     {
                        // We haven't overpassed the existing start block
                        // so just trim back the end block.
                        mBlockEnd = newpos;
                     }
                     else if ( newpos == mBlockStart )
                     {
                        // We are back at the start, so no more selection.
                        mBlockEnd = mBlockStart = 0;
                     }
                     else
                     {
                        // Only other option, we just backtracked PAST
                        // our original start block.
                        // So the new position becomes the start block
                        // and the old start block becomes the end block.
                        mBlockEnd = mBlockStart;
                        mBlockStart = newpos;
                     }
                  }
               }
                              
               mCursorPos = newpos;

               return true;
            }

            case KEY_RIGHT:
            {
               S32 newpos = findNextWord();               

               if ( mBlockStart == mBlockEnd )
               {
                  // There was not already a selection so start a new one.
                  mBlockStart = mCursorPos;
                  mBlockEnd = newpos;
               }
               else
               {
                  // There was a selection already...
                  // In this case the cursor MUST be at either the
                  // start or end of that selection.

                  if ( mCursorPos == mBlockEnd )
                  {
                     // We are at the end block and traveling right so
                     // just extend the end block farther right.                     
                     mBlockEnd = newpos;
                  }
                  else
                  {
                     // We are at the start block BUT traveling right
                     // back towards the end block...

                     if ( newpos < mBlockEnd )
                     {
                        // We haven't overpassed the existing end block
                        // so just trim back the start block.
                        mBlockStart = newpos;
                     }
                     else if ( newpos == mBlockEnd )
                     {
                        // We are back at the end, so no more selection.
                        mBlockEnd = mBlockStart = 0;
                     }
                     else
                     {
                        // Only other option, we just backtracked PAST
                        // our original end block.
                        // So the new position becomes the end block
                        // and the old end block becomes the start block.
                        mBlockStart = mBlockEnd;
                        mBlockEnd = newpos;
                     }
                  }
               }

               mCursorPos = newpos;

               return true;
            }
            
            default:
               break;
         }
      }

      // End support for word jump selection.


        switch ( event.keyCode )
        {
            case KEY_TAB:
               if ( mTabComplete )
               {
				  onTabComplete_callback("1");
                  return true;
               }
			   break; // We don't want to fall through if we don't handle the TAB here.

            case KEY_HOME:
               mBlockStart = 0;
               mBlockEnd = mCursorPos;
               mCursorPos = 0;
               return true;

            case KEY_END:
                mBlockStart = mCursorPos;
                mBlockEnd = stringLen;
                mCursorPos = stringLen;
                return true;

            case KEY_LEFT:
                if ((mCursorPos > 0) & (stringLen > 0))
                {
                    //if we already have a selected block
                    if (mCursorPos == mBlockEnd)
                    {
                        mCursorPos--;
                        mBlockEnd--;
                        if (mBlockEnd == mBlockStart)
                        {
                            mBlockStart = 0;
                            mBlockEnd = 0;
                        }
                    }
                    else {
                        mCursorPos--;
                        mBlockStart = mCursorPos;

                        if (mBlockEnd == 0)
                        {
                            mBlockEnd = mCursorPos + 1;
                        }
                    }
                }
                return true;

            case KEY_RIGHT:
                if (mCursorPos < stringLen)
                {
                    if ((mCursorPos == mBlockStart) && (mBlockEnd > 0))
                    {
                        mCursorPos++;
                        mBlockStart++;
                        if (mBlockStart == mBlockEnd)
                        {
                            mBlockStart = 0;
                            mBlockEnd = 0;
                        }
                    }
                    else
                    {
                        if (mBlockEnd == 0)
                        {
                            mBlockStart = mCursorPos;
                            mBlockEnd = mCursorPos;
                        }
                        mCursorPos++;
                        mBlockEnd++;
                    }
                }
                return true;

				case KEY_RETURN:
				case KEY_NUMPADENTER:
           
					return dealWithEnter(false);

            default:
               break;
        }
    }
   else if (event.modifier & SI_CTRL)
   {
      switch(event.keyCode)
      {
#if defined(TORQUE_OS_MAC)
         // Added UNIX emacs key bindings - just a little hack here...

         // Ctrl-B - move one character back
         case KEY_B:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_LEFT;
            return(onKeyDown(new_event));
         }

         // Ctrl-F - move one character forward
         case KEY_F:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_RIGHT;
            return(onKeyDown(new_event));
         }

         // Ctrl-A - move to the beginning of the line
         case KEY_A:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_HOME;
            return(onKeyDown(new_event));
         }

         // Ctrl-E - move to the end of the line
         case KEY_E:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_END;
            return(onKeyDown(new_event));
         }

         // Ctrl-P - move backward in history
         case KEY_P:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_UP;
            return(onKeyDown(new_event));
         }

         // Ctrl-N - move forward in history
         case KEY_N:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_DOWN;
            return(onKeyDown(new_event));
         }

         // Ctrl-D - delete under cursor
         case KEY_D:
         { 
            GuiEvent new_event;
            new_event.modifier = 0;
            new_event.keyCode = KEY_DELETE;
            return(onKeyDown(new_event));
         }

         case KEY_U:
         { 
            GuiEvent new_event;
            new_event.modifier = SI_CTRL;
            new_event.keyCode = KEY_DELETE;
            return(onKeyDown(new_event));
         }

         // End added UNIX emacs key bindings
#endif

         // Adding word jump navigation.

         case KEY_LEFT:
         {

            mCursorPos = findPrevWord();
            mBlockStart = 0;
            mBlockEnd = 0;
            return true;
         }

         case KEY_RIGHT:
         {
            mCursorPos = findNextWord();
            mBlockStart = 0;
            mBlockEnd = 0;
            return true;
         }         
         
#if !defined(TORQUE_OS_MAC)
         // Select all
         case KEY_A:
         {
            selectAllText();
            return true;
         }

         // windows style cut / copy / paste / undo keybinds
         case KEY_C:
         case KEY_X:
         {
            // copy, and cut the text if we hit ctrl-x
            onCopy( event.keyCode==KEY_X );
            return true;
         }
         case KEY_V:
         {
            onPaste();

            // Execute the console command!
            execConsoleCallback();
            return true;
         }

         case KEY_Z:
            if (! mDragHit)
            {
               onUndo();
               return true;
            }
#endif

         case KEY_DELETE:
         case KEY_BACKSPACE:
            //save the current state
            saveUndoState();

            //delete everything in the field
            mTextBuffer.set("");
            mCursorPos  = 0;
            mBlockStart = 0;
            mBlockEnd   = 0;

            execConsoleCallback();
            onChangeCursorPos(); //.logicking
            return true;
         default:
            break;
      }
   }
#if defined(TORQUE_OS_MAC)
   // mac style cut / copy / paste / undo keybinds
   else if (event.modifier & SI_ALT)
   {
      // Mac command key maps to alt in torque.

      // Added Mac cut/copy/paste/undo keys
      switch(event.keyCode)
      {
         // Select all
         case KEY_A:
         {
            selectAllText();
            return true;
         }
         case KEY_C:
         case KEY_X:
         {
            // copy, and cut the text if we hit cmd-x
            onCopy( event.keyCode==KEY_X );
            return true;
         }
         case KEY_V:
         {
            onPaste();

            // Execute the console command!
            execConsoleCallback();

            return true;
         }
            
         case KEY_Z:
            if (! mDragHit)
            {
               onUndo();
               return true;
            }
            
         default:
            break;
      }
   }
#endif
   else
   {
      switch(event.keyCode)
      {
         case KEY_ESCAPE:
            if( mEscapeCommand.isNotEmpty() )
            {
               evaluate( mEscapeCommand );
               return( true );
            }
            return( Parent::onKeyDown( event ) );

         case KEY_RETURN:
         case KEY_NUMPADENTER:
           
				return dealWithEnter(true);

         case KEY_UP:
         {
            if( mHistorySize > 0 )
            {
               if(mHistoryDirty)
               {
                  updateHistory(&mTextBuffer, false);
                  mHistoryDirty = false;
               }

               mHistoryIndex--;
               
               if(mHistoryIndex >= 0 && mHistoryIndex <= mHistoryLast)
                  setText(mHistoryBuf[mHistoryIndex]);
               else if(mHistoryIndex < 0)
                  mHistoryIndex = 0;
            }
               
            return true;
         }

         case KEY_DOWN:
         {
            if( mHistorySize > 0 )
            {
               if(mHistoryDirty)
               {
                  updateHistory(&mTextBuffer, false);
                  mHistoryDirty = false;
               }
               mHistoryIndex++;
               if(mHistoryIndex > mHistoryLast)
               {
                  mHistoryIndex = mHistoryLast + 1;
                  setText("");
               }
               else
                  setText(mHistoryBuf[mHistoryIndex]);
            }
            return true;
         }

         case KEY_LEFT:
            
            // If we have a selection put the cursor to the left side of it.
            if ( mBlockStart != mBlockEnd )
            {
               mCursorPos = mBlockStart;
               mBlockStart = mBlockEnd = 0;
            }
            else
            {
               mBlockStart = mBlockEnd = 0;
               mCursorPos = getMax( mCursorPos - 1, 0 );               
            }

            return true;

         case KEY_RIGHT:

            // If we have a selection put the cursor to the right side of it.            
            if ( mBlockStart != mBlockEnd )
            {
               mCursorPos = mBlockEnd;
               mBlockStart = mBlockEnd = 0;
            }
            else
            {
               mBlockStart = mBlockEnd = 0;
               mCursorPos = getMin( mCursorPos + 1, stringLen );               
            }

            return true;

         case KEY_BACKSPACE:
dealWithBackspace:
            //save the current state
            saveUndoState();

            if (mBlockEnd > 0)
            {
               mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
               mCursorPos  = mBlockStart;
               mBlockStart = 0;
               mBlockEnd   = 0;
               mHistoryDirty = true;

               // Execute the console command!
               execConsoleCallback();

            }
            else if (mCursorPos > 0)
            {
               mTextBuffer.cut(mCursorPos-1, 1);
               mCursorPos--;
               mHistoryDirty = true;

               // Execute the console command!
               execConsoleCallback();
            }
            return true;

         case KEY_DELETE:
            //save the current state
            saveUndoState();

            if (mBlockEnd > 0)
            {
               mHistoryDirty = true;
               mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);

               mCursorPos = mBlockStart;
               mBlockStart = 0;
               mBlockEnd = 0;

               // Execute the console command!
               execConsoleCallback();
            }
            else if (mCursorPos < stringLen)
            {
               mHistoryDirty = true;
               mTextBuffer.cut(mCursorPos, 1);

               // Execute the console command!
               execConsoleCallback();
            }
            return true;

         case KEY_INSERT:
            mInsertOn = !mInsertOn;
            return true;

         case KEY_HOME:
            mBlockStart = 0;
            mBlockEnd   = 0;
            mCursorPos  = 0;
            return true;

         case KEY_END:
            mBlockStart = 0;
            mBlockEnd   = 0;
            mCursorPos  = stringLen;
            return true;
      
         default:
            break;

         }
   }

   switch ( event.keyCode )
   {
      case KEY_TAB:
         if ( mTabComplete )
         {
			onTabComplete_callback("0");
            return( true );
         }
      case KEY_UP:
      case KEY_DOWN:
      case KEY_ESCAPE:
         return Parent::onKeyDown( event );
      default:
         break;
   }
         
   // Handle character input events.

   if( mProfile->mFont->isValidChar( event.ascii ) )
   {
      handleCharInput( event.ascii );
      return true;
   }

   // Or eat it if that's appropriate.
   if( mSinkAllKeyEvents )
      return true;

   // Not handled - pass the event to it's parent.
   return Parent::onKeyDown( event );
}
void GuiTextEditCtrl::handleCharInput( U16 ascii )
{
   S32 stringLen = mTextBuffer.length();

   // Get the character ready to add to a UTF8 string.
   UTF16 convertedChar[2] = { ascii, 0 };

   //see if it's a number field
   if ( mProfile->mNumbersOnly )
   {
      if ( ascii == '-')
      {
         //a minus sign only exists at the beginning, and only a single minus sign
         if ( mCursorPos != 0 && !isAllTextSelected() )
         {
            playDeniedSound();
            return;
         }

         if ( mInsertOn && ( mTextBuffer.getChar(0) == '-' ) ) 
         {
            playDeniedSound();
            return;
         }
      }
      // BJTODO: This is probably not unicode safe.
      else if (  ascii != '.' && (ascii < '0' || ascii > '9')  )
      {
         playDeniedSound();
         return;
      }
   }

   //save the current state
   saveUndoState();

   bool alreadyCut = false;

   //delete anything highlighted
   if ( mBlockEnd > 0 )
   {
      mTextBuffer.cut(mBlockStart, mBlockEnd-mBlockStart);
      mCursorPos  = mBlockStart;
      mBlockStart = 0;
      mBlockEnd   = 0;

      // We just changed the string length!
      // Get its new value.
      stringLen = mTextBuffer.length();

      // If we already had text highlighted, we just want to cut that text.
      // Don't cut the next character even if insert is not on.
      alreadyCut = true;
   }

   if ( ( mInsertOn && ( stringLen < mMaxStrLen ) ) ||
      ( !mInsertOn && ( mCursorPos < mMaxStrLen ) ) )
   {
      if ( mCursorPos == stringLen )
      {
         mTextBuffer.append(convertedChar);
         mCursorPos++;
      }
      else
      {
         if ( mInsertOn || alreadyCut )
         {
            mTextBuffer.insert(mCursorPos, convertedChar);
            mCursorPos++;
         }
         else
         {
            mTextBuffer.cut(mCursorPos, 1);
            mTextBuffer.insert(mCursorPos, convertedChar);
            mCursorPos++;
         }
      }
   }
   else
      playDeniedSound();

   //reset the history index
   mHistoryDirty = true;

   //execute the console command if it exists
   execConsoleCallback();
}
Exemplo n.º 7
0
int WDL_CursesEditor::onChar(int c)
{
  if (m_state == -3 || m_state == -4)
  {
    switch (c)
    {
       case '\r': case '\n':
         m_state=0;
         runSearch();
       break;
       case 27: 
         m_state=0; 
         draw();
         setCursor();
         draw_message("Find cancelled.");
       break;
       case KEY_BACKSPACE: if (s_search_string[0]) s_search_string[strlen(s_search_string)-1]=0; m_state=-4; break;
       default: 
         if (VALIDATE_TEXT_CHAR(c)) 
         { 
           int l=m_state == -3 ? 0 : strlen(s_search_string); 
           m_state = -4;
           if (l < (int)sizeof(s_search_string)-1) { s_search_string[l]=c; s_search_string[l+1]=0; } 
         } 
        break;
     }
     if (m_state)
     {
       attrset(m_color_message);
       bkgdset(m_color_message);
       mvaddstr(LINES-1,29,s_search_string);
       clrtoeol(); 
       attrset(0);
       bkgdset(0);
     }
     return 0;
  }
  if (c==KEY_DOWN || c==KEY_UP || c==KEY_PPAGE||c==KEY_NPAGE || c==KEY_RIGHT||c==KEY_LEFT||c==KEY_HOME||c==KEY_END)
  {
    if (SHIFT_KEY_DOWN)      
    {
      if (!m_selecting)
      {
        m_select_x2=m_select_x1=m_curs_x; m_select_y2=m_select_y1=m_curs_y;
        m_selecting=1;
      }
    }
    else if (m_selecting) { m_selecting=0; draw(); }
  }

  switch(c)
  {
    case 'O'-'A'+1:
      if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
      {
        if (m_pane_div <= 0.0 || m_pane_div >= 1.0)
        {
          onChar('P'-'A'+1);
        }
        if (m_pane_div > 0.0 && m_pane_div < 1.0) 
        {
          m_curpane=!m_curpane;
          draw();
          draw_status_state();
          int paney[2], paneh[2];
          GetPaneDims(paney, paneh);
          if (m_curs_y-m_paneoffs_y[m_curpane] < 0) m_curs_y=m_paneoffs_y[m_curpane];
          else if (m_curs_y-m_paneoffs_y[m_curpane] >= paneh[m_curpane]) m_curs_y=paneh[m_curpane]+m_paneoffs_y[m_curpane]-1;
          setCursor();
        }
      }
    break;
    case 'P'-'A'+1:
      if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
      {
        if (m_pane_div <= 0.0 || m_pane_div >= 1.0) 
        {
          m_pane_div=0.5;
          m_paneoffs_y[1]=m_paneoffs_y[0];
        }
        else 
        {
          m_pane_div=1.0;
          if (m_curpane) m_paneoffs_y[0]=m_paneoffs_y[1];
          m_curpane=0;
        }
        draw();
        draw_status_state();

        int paney[2], paneh[2];
        const int pane_divy=GetPaneDims(paney, paneh);
        setCursor();
      }
    break;
    
    case 407:
    case 'Z'-'A'+1:
      if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
      {
        if (m_undoStack_pos > 0)
        {
           m_undoStack_pos--;
           loadUndoState(m_undoStack.Get(m_undoStack_pos));
           draw();
           setCursor();
           char buf[512];
           snprintf(buf,sizeof(buf),"Undid action - %d items in undo buffer",m_undoStack_pos);
           draw_message(buf);
        }
        else 
        {
          draw_message("Can't Undo");
        }   
        break;
      }
    // fall through
    case 'Y'-'A'+1:
      if ((c == 'Z'-'A'+1 || !SHIFT_KEY_DOWN) && !ALT_KEY_DOWN)
      {
        if (m_undoStack_pos < m_undoStack.GetSize()-1)
        {
          m_undoStack_pos++;
          loadUndoState(m_undoStack.Get(m_undoStack_pos));
          draw();
          setCursor();
          char buf[512];
          snprintf(buf,sizeof(buf),"Redid action - %d items in redo buffer",m_undoStack.GetSize()-m_undoStack_pos-1);
          draw_message(buf);
        }
        else 
        {
          draw_message("Can't Redo");  
        }
      }
    break;
    case KEY_IC:
      if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
      {
        s_overwrite=!s_overwrite;
        setCursor();
        break;
      }
      // fqll through
    case 'V'-'A'+1:
      if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
      {
        // generate a m_clipboard using win32 clipboard data
        WDL_PtrList<const char> lines;
        WDL_String buf;
#ifdef WDL_IS_FAKE_CURSES
        if (CURSES_INSTANCE)
        {
          OpenClipboard(CURSES_INSTANCE->m_hwnd);
          HANDLE h=GetClipboardData(CF_TEXT);
          if (h)
          {
            char *t=(char *)GlobalLock(h);
            int s=GlobalSize(h);
            buf.Set(t,s);
            GlobalUnlock(t);        
          }
          CloseClipboard();
        }
        else
#endif
        {
          buf.Set(s_fake_clipboard.Get());
        }

        if (buf.Get() && buf.Get()[0])
        {
          char *src=buf.Get();
          while (*src)
          {
            char *seek=src;
            while (*seek && *seek != '\r' && *seek != '\n') seek++;
            char hadclr=*seek;
            if (*seek) *seek++=0;
            lines.Add(src);

            if (hadclr == '\r' && *seek == '\n') seek++;

            if (hadclr && !*seek)
            {
              lines.Add("");
            }
            src=seek;
          }
        }
        if (lines.GetSize())
        {
          removeSelect();
          // insert lines at m_curs_y,m_curs_x
          if (m_curs_y >= m_text.GetSize()) m_curs_y=m_text.GetSize()-1;
          if (m_curs_y < 0) m_curs_y=0;

          preSaveUndoState();
          WDL_FastString poststr;
          int x;
          int indent_to_pos = -1;
          for (x = 0; x < lines.GetSize(); x ++)
          {
            WDL_FastString *str=m_text.Get(m_curs_y);
            const char *tstr=lines.Get(x);
            if (!tstr) tstr="";
            if (!x)
            {
              if (str)
              {
                if (m_curs_x < 0) m_curs_x=0;
                int tmp=str->GetLength();
                if (m_curs_x > tmp) m_curs_x=tmp;
  
                poststr.Set(str->Get()+m_curs_x);
                str->SetLen(m_curs_x);

                const char *p = str->Get();
                while (*p == ' ' || *p == '\t') p++;
                if (!*p && p > str->Get())
                {
                  if (lines.GetSize()>1)
                  {
                    while (*tstr == ' ' || *tstr == '\t') tstr++;
                  }
                  indent_to_pos = m_curs_x;
                }

                str->Append(tstr);
              }
              else
              {
                m_text.Insert(m_curs_y,(str=new WDL_FastString(tstr)));
              }
              if (lines.GetSize() > 1)
              {
                m_curs_y++;
              }
              else
              {
                m_curs_x = str->GetLength();
                str->Append(poststr.Get());
              }
           }
           else if (x == lines.GetSize()-1)
           {
             WDL_FastString *s=newIndentedFastString(tstr,indent_to_pos);
             m_curs_x = s->GetLength();
             s->Append(poststr.Get());
             m_text.Insert(m_curs_y,s);
           }
           else
           {
             m_text.Insert(m_curs_y,newIndentedFastString(tstr,indent_to_pos));
             m_curs_y++;
           }
         }
         draw();
         setCursor();
         draw_message("Pasted");
         saveUndoState();
       }
       else 
       {
         setCursor();
         draw_message("Clipboard empty");
       }
     }
  break;

  case KEY_DC:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
    {
      WDL_FastString *s;
      if (m_selecting)
      {
        preSaveUndoState();
        removeSelect();
        draw();
        saveUndoState();
        setCursor();
      }
      else if ((s=m_text.Get(m_curs_y)))
      {
        if (m_curs_x < s->GetLength())
        {
          preSaveUndoState();

          bool hadCom = LineCanAffectOtherLines(s->Get(),m_curs_x,1); 
          s->DeleteSub(m_curs_x,1);
          if (!hadCom) hadCom = LineCanAffectOtherLines(s->Get(),-1,-1);
          draw(hadCom ? -1 : m_curs_y);
          saveUndoState();
          setCursor();
        }
        else // append next line to us
        {
          if (m_curs_y < m_text.GetSize()-1)
          {
            preSaveUndoState();

            WDL_FastString *nl=m_text.Get(m_curs_y+1);
            if (nl)
            {
              s->Append(nl->Get());
            }
            m_text.Delete(m_curs_y+1,true);

            draw();
            saveUndoState();
            setCursor();
          }
        }
      }
      break;
    }
  case 'C'-'A'+1:
  case 'X'-'A'+1:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN && m_selecting)
    {
      if (c!= 'C'-'A'+1) m_selecting=0;
      int miny,maxy,minx,maxx;
      int x;
      getselectregion(minx,miny,maxx,maxy);
      const char *status="";
      char statusbuf[512];

      if (minx != maxx|| miny != maxy) 
      {
        int bytescopied=0;
        s_fake_clipboard.Set("");

        int lht=0,fht=0;
        if (c != 'C'-'A'+1) preSaveUndoState();

        for (x = miny; x <= maxy; x ++)
        {
          WDL_FastString *s=m_text.Get(x);
          if (s) 
          {
            const char *str=s->Get();
            int sx,ex;
            if (x == miny) sx=max(minx,0);
            else sx=0;
            int tmp=s->GetLength();
            if (sx > tmp) sx=tmp;
      
            if (x == maxy) ex=min(maxx,tmp);
            else ex=tmp;
      
            bytescopied += ex-sx + (x!=maxy);
            if (s_fake_clipboard.Get() && s_fake_clipboard.Get()[0]) s_fake_clipboard.Append("\r\n");
            s_fake_clipboard.Append(ex-sx?str+sx:"",ex-sx);

            if (c != 'C'-'A'+1)
            {
              if (sx == 0 && ex == tmp) // remove entire line
              {
                m_text.Delete(x,true);
                if (x==miny) miny--;
                x--;
                maxy--;
              }
              else { if (x==miny) fht=1; if (x == maxy) lht=1; s->DeleteSub(sx,ex-sx); }
            }
          }
        }
        if (fht && lht && miny+1 == maxy)
        {
          m_text.Get(miny)->Append(m_text.Get(maxy)->Get());
          m_text.Delete(maxy,true);
        }
        if (c != 'C'-'A'+1)
        {
          m_curs_y=miny;
          if (m_curs_y < 0) m_curs_y=0;
          m_curs_x=minx;
          saveUndoState();
          snprintf(statusbuf,sizeof(statusbuf),"Cut %d bytes",bytescopied);
        }
        else
          snprintf(statusbuf,sizeof(statusbuf),"Copied %d bytes",bytescopied);

#ifdef WDL_IS_FAKE_CURSES
        if (CURSES_INSTANCE)
        {
          int l=s_fake_clipboard.GetLength()+1;
          HANDLE h=GlobalAlloc(GMEM_MOVEABLE,l);
          void *t=GlobalLock(h);
          memcpy(t,s_fake_clipboard.Get(),l);
          GlobalUnlock(h);
          OpenClipboard(CURSES_INSTANCE->m_hwnd);
          EmptyClipboard();
          SetClipboardData(CF_TEXT,h);
          CloseClipboard();
        }
#endif

        status=statusbuf;
      }
      else status="No selection";

      draw();
      setCursor();
      draw_message(status);
    }
  break;
  case 'A'-'A'+1:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
    {
      m_selecting=1;
      m_select_x1=0;
      m_select_y1=0;
      m_select_y2=m_text.GetSize()-1;
      m_select_x2=0;
      if (m_text.Get(m_select_y2))
        m_select_x2=m_text.Get(m_select_y2)->GetLength();
      draw();
      setCursor();
    }
  break;
  case 27:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN && m_selecting)
    {
      m_selecting=0;
      draw();
      setCursor();
      break;
    }
  break;
  case KEY_F3:
  case 'G'-'A'+1:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN && s_search_string[0])
    {
      runSearch();
      return 0;
    }
  // fall through
  case 'F'-'A'+1:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
    {
      draw_message("");
      attrset(m_color_message);
      bkgdset(m_color_message);
      mvaddstr(LINES-1,0,"Find string (ESC to cancel): ");
      if (m_selecting && m_select_y1==m_select_y2)
      {
        WDL_FastString* s=m_text.Get(m_select_y1);
        if (s)
        {
          const char* p=s->Get();
          int xlo=min(m_select_x1, m_select_x2);
          int xhi=max(m_select_x1, m_select_x2);
          int i;
          for (i=xlo; i < xhi; ++i)
          {
            if (!isalnum(p[i]) && p[i] != '_') break;
          }
          if (i == xhi && xhi > xlo && xhi-xlo < sizeof(s_search_string))
          {
            lstrcpyn(s_search_string, p+xlo, xhi-xlo+1);
          }
        }
      }
      addstr(s_search_string);
      clrtoeol();
      attrset(0);
      bkgdset(0);
      m_state=-3; // find, initial (m_state=4 when we've typed something)
    }
  break;
  case KEY_DOWN:
    {
      if (CTRL_KEY_DOWN)
      {
        int paney[2], paneh[2];
        GetPaneDims(paney, paneh);
        int maxscroll=m_text.GetSize()-paneh[m_curpane]+4;
        if (m_paneoffs_y[m_curpane] < maxscroll-1)
        {
          m_paneoffs_y[m_curpane]++;
          if (m_curs_y < m_paneoffs_y[m_curpane]) m_curs_y=m_paneoffs_y[m_curpane];
          draw();
        }
      }
      else
      {
        m_curs_y++;
        if (m_curs_y>=m_text.GetSize()) m_curs_y=m_text.GetSize()-1;
        if (m_curs_y < 0) m_curs_y=0;
      }
      if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); }
      setCursor(1);
    }
  break;
  case KEY_UP:
    {
      if (CTRL_KEY_DOWN)
      {
        if (m_paneoffs_y[m_curpane] > 0)
        {
          int paney[2], paneh[2];
          GetPaneDims(paney, paneh);
          m_paneoffs_y[m_curpane]--;
          if (m_curs_y >  m_paneoffs_y[m_curpane]+paneh[m_curpane]-1) m_curs_y = m_paneoffs_y[m_curpane]+paneh[m_curpane]-1;
          if (m_curs_y < 0) m_curs_y=0;
          draw();
        }
      }
      else
      {
        if(m_curs_y>0) m_curs_y--;
      }
      if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); }
      setCursor(1);
    }
  break;
  case KEY_PPAGE:
    {
      if (m_curs_y > m_paneoffs_y[m_curpane])
      {
        m_curs_y=m_paneoffs_y[m_curpane];
        if (m_curs_y < 0) m_curs_y=0;
      }
      else 
      {
        int paney[2], paneh[2];
        GetPaneDims(paney, paneh);
        m_curs_y -= paneh[m_curpane];
        if (m_curs_y < 0) m_curs_y=0;
        m_paneoffs_y[m_curpane]=m_curs_y;
      }
      if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; }
      draw();
      setCursor(1);
    }
  break; 
  case KEY_NPAGE:
    {
      int paney[2], paneh[2]; 
      GetPaneDims(paney, paneh);
      if (m_curs_y >= m_paneoffs_y[m_curpane]+paneh[m_curpane]-1) m_paneoffs_y[m_curpane]=m_curs_y-1;
      m_curs_y = m_paneoffs_y[m_curpane]+paneh[m_curpane]-1;
      if (m_curs_y >= m_text.GetSize()) m_curs_y=m_text.GetSize()-1;
      if (m_curs_y < 0) m_curs_y=0;
      if (m_selecting) { setCursor(1); m_select_x2=m_curs_x; m_select_y2=m_curs_y; }
      draw();
      setCursor(1);
    }
  break;
  case KEY_RIGHT:
    {
      if (1) // wrap across lines
      {
        WDL_FastString *s = m_text.Get(m_curs_y);
        if (s && m_curs_x >= s->GetLength() && m_curs_y < m_text.GetSize()) { m_curs_y++; m_curs_x = -1; }
      }

      if(m_curs_x<0) 
      {
        m_curs_x=0;
      }
      else
      {
        if (CTRL_KEY_DOWN)
        {
          WDL_FastString *s = m_text.Get(m_curs_y);
          if (!s||m_curs_x >= s->GetLength()) break;
          int lastType = categorizeCharForWordNess(s->Get()[m_curs_x++]);
          while (m_curs_x < s->GetLength())
          {
            int thisType = categorizeCharForWordNess(s->Get()[m_curs_x]);
            if (thisType != lastType && thisType != 0) break;
            lastType=thisType;
            m_curs_x++;
          }
        }
        else 
        {
          m_curs_x++;
        }
      }
      if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); }
      setCursor();
    }
  break;
  case KEY_LEFT:
    {
      bool doMove=true;
      if (1) // wrap across lines
      {
        WDL_FastString *s = m_text.Get(m_curs_y);
        if (s && m_curs_y>0 && m_curs_x == 0) 
        { 
          s = m_text.Get(--m_curs_y);
          if (s) 
          {
            m_curs_x = s->GetLength(); 
            doMove=false;
          }
        }
      }

      if(m_curs_x>0 && doMove) 
      {
        if (CTRL_KEY_DOWN)
        {
          WDL_FastString *s = m_text.Get(m_curs_y);
          if (!s) break;
          if (m_curs_x > s->GetLength()) m_curs_x = s->GetLength();
          m_curs_x--;

          int lastType = categorizeCharForWordNess(s->Get()[m_curs_x--]);
          while (m_curs_x >= 0)
          {
            int thisType = categorizeCharForWordNess(s->Get()[m_curs_x]);
            if (thisType != lastType && lastType != 0) break;
            lastType=thisType;
            m_curs_x--;
          }
          m_curs_x++;
        }
        else 
        {
          m_curs_x--;
        }
      }
      if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); }
      setCursor();
    }
  break;
  case KEY_HOME:
    {
      m_curs_x=0;
      if (CTRL_KEY_DOWN) m_curs_y=0;
      if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); }
      setCursor();
    }
  break;
  case KEY_END:
    {
      if (m_text.Get(m_curs_y)) m_curs_x=m_text.Get(m_curs_y)->GetLength();
      if (CTRL_KEY_DOWN) m_curs_y=m_text.GetSize();
      if (m_selecting) { setCursor(); m_select_x2=m_curs_x; m_select_y2=m_curs_y; draw(); }
      setCursor();
    }
  break;
  case KEY_BACKSPACE: // backspace, baby
    if (m_selecting)
    {
      preSaveUndoState();
      removeSelect();
      draw();
      saveUndoState();
      setCursor();
    }
    else if (m_curs_x > 0)
    {
      WDL_FastString *tl=m_text.Get(m_curs_y);
      if (tl)
      {
        preSaveUndoState();

        bool hadCom = LineCanAffectOtherLines(tl->Get(), m_curs_x-1,1);
        tl->DeleteSub(--m_curs_x,1);
        if (!hadCom) hadCom = LineCanAffectOtherLines(tl->Get(),-1,-1);
        draw(hadCom?-1:m_curs_y);
        saveUndoState();
        setCursor();
      }
    }
    else // append current line to previous line
    {
      WDL_FastString *fl=m_text.Get(m_curs_y-1), *tl=m_text.Get(m_curs_y);
      if (!tl) 
      {
        m_curs_y--;
        if (fl) m_curs_x=fl->GetLength();
        draw();
        saveUndoState();
        setCursor();
      }
      else if (fl)
      {
        preSaveUndoState();
        m_curs_x=fl->GetLength();
        fl->Append(tl->Get());

        m_text.Delete(m_curs_y--,true);
        draw();
        saveUndoState();
        setCursor();
      }
    }
  break;
  case 'L'-'A'+1:
    if (!SHIFT_KEY_DOWN && !ALT_KEY_DOWN)
    {
      draw();
      setCursor();
    }
  break;
  case 13: //KEY_ENTER:
    //insert newline
    preSaveUndoState();

    if (m_selecting) { removeSelect(); draw(); setCursor(); }
    if (m_curs_y >= m_text.GetSize())
    {
      m_curs_y=m_text.GetSize();
      m_text.Add(new WDL_FastString);
    }
    if (s_overwrite)
    {
      WDL_FastString *s = m_text.Get(m_curs_y);
      int plen=0;
      const char *pb=NULL;
      if (s)
      {
        pb = s->Get();
        while (plen < m_curs_x && (pb[plen]== ' ' || pb[plen] == '\t')) plen++;
      }
      if (++m_curs_y >= m_text.GetSize())
      {
        m_curs_y = m_text.GetSize();
        WDL_FastString *ns=new WDL_FastString;
        if (plen>0) ns->Set(pb,plen);
        m_text.Insert(m_curs_y,ns);
      }
      s = m_text.Get(m_curs_y);
      if (s && plen > s->GetLength()) plen=s->GetLength();
      m_curs_x=plen;
    }
    else 
    {
      WDL_FastString *s = m_text.Get(m_curs_y);
      if (s)
      {
        if (m_curs_x > s->GetLength()) m_curs_x = s->GetLength();
        WDL_FastString *nl = new WDL_FastString();
        int plen=0;
        const char *pb = s->Get();
        while (plen < m_curs_x && (pb[plen]== ' ' || pb[plen] == '\t')) plen++;

        if (plen>0) nl->Set(pb,plen);

        nl->Append(pb+m_curs_x);
        m_text.Insert(++m_curs_y,nl);
        s->SetLen(m_curs_x);
        m_curs_x=plen;
      }
    }
    m_offs_x=0;

    draw();
    saveUndoState();
    setCursor();
  break;
  case '\t':
    if (m_selecting)
    {
      preSaveUndoState();

      bool isRev = !!(GetAsyncKeyState(VK_SHIFT)&0x8000);
      indentSelect(isRev?-m_indent_size:m_indent_size);
      // indent selection:
      draw();
      setCursor();
      saveUndoState();
      break;
    }
  default:
    //insert char
    if(VALIDATE_TEXT_CHAR(c))
    { 
      preSaveUndoState();

      if (m_selecting) { removeSelect(); draw(); setCursor(); }
      if (!m_text.Get(m_curs_y)) m_text.Insert(m_curs_y,new WDL_FastString);

      WDL_FastString *ss;
      if ((ss=m_text.Get(m_curs_y)))
      {
        char str[64];
        int slen ;
        if (c == '\t') 
        {
          slen = min(m_indent_size,64);
          if (slen<1) slen=1;
          int x; 
          for(x=0;x<slen;x++) str[x]=' ';
        }
        else
        {
          str[0]=c;
          slen = 1;
        }


        bool hadCom = LineCanAffectOtherLines(ss->Get(),-1,-1);
        if (s_overwrite)
        {
          if (!hadCom) hadCom = LineCanAffectOtherLines(ss->Get(),m_curs_x,slen);
          ss->DeleteSub(m_curs_x,slen);
        }
        ss->Insert(str,m_curs_x,slen);
        if (!hadCom) hadCom = LineCanAffectOtherLines(ss->Get(),m_curs_x,slen);

        m_curs_x += slen;

        draw(hadCom ? -1 : m_curs_y);
      }
      saveUndoState();
      setCursor();
    }
    break;
  }
  return 0;
}
Exemplo n.º 8
0
void TextEdit::onKeyDown(const Event &event)
{
   int stringLen = strlen(text);
   setUpdate();
   
    if (event.modifier & SI_SHIFT)
    {
        switch(event.diKeyCode)
        {
             case DIK_HOME:
                blockStart = 0;
                blockEnd = cursorPos;
                cursorPos = 0;
                return;
                
             case DIK_END:
                blockStart = cursorPos;
                blockEnd = stringLen;
                cursorPos = stringLen;
                return;
            
            case DIK_LEFT:
                if ((cursorPos > 0) & (stringLen > 0))
                {
                    //if we already have a selected block
                    if (cursorPos == blockEnd)
                    {
                        cursorPos--;
                        blockEnd--;
                        if (blockEnd == blockStart)
                        {
                            blockStart = 0;
                            blockEnd = 0;
                        }
                    }
                    else {
                        cursorPos--;
                        blockStart = cursorPos;
                        
                        if (blockEnd == 0)
                        {
                            blockEnd = cursorPos + 1;
                        }
                    }
                }
                return;
                
            case DIK_RIGHT:
                if (cursorPos < stringLen)
                {
                    if ((cursorPos == blockStart) && (blockEnd > 0))
                    {
                        cursorPos++;
                        blockStart++;
                        if (blockStart == blockEnd)
                        {
                            blockStart = 0;
                            blockEnd = 0;
                        }
                    }
                    else
                    {
                        if (blockEnd == 0)
                        {
                            blockStart = cursorPos;
                            blockEnd = cursorPos;
                        }
                        cursorPos++;
                        blockEnd++;
                    }
                }
                return;
        }
    }
   else if (event.modifier & SI_CTRL)
   {
      switch(event.diKeyCode)
      {
         case DIK_C:
         case DIK_X:
            if (blockEnd > 0)
            {
                //save the current state
                saveUndoState();
                
                char buf[SimpleText::MAX_STRING_LENGTH + 1], temp;
                
                //copy to the clipboard    
                if (!OpenClipboard(getCanvas()->getHandle()))
                    return;
                LPTSTR  lptstrCopy; 
                HGLOBAL hglbCopy;
                hglbCopy = GlobalAlloc(GMEM_DDESHARE, (blockEnd - blockStart + 1)); 
                if (hglbCopy == NULL) 
                { 
                    CloseClipboard(); 
                    return; 
                } 

                // Lock the handle and copy the text to the buffer. 
                temp = text[blockEnd];
                text[blockEnd] = '\0';
                lptstrCopy = (char*)(GlobalLock(hglbCopy)); 
                strcpy(lptstrCopy, &text[blockStart]); 
                text[blockEnd] = temp;

                GlobalUnlock(hglbCopy);

                // Place the handle on the clipboard. 
                SetClipboardData(CF_TEXT, hglbCopy); 
                
                CloseClipboard();
                
                if (event.diKeyCode == DIK_X)
                {
                    strcpy(buf, &text[blockEnd]);
                    cursorPos = blockStart;
                    strcpy(&text[blockStart], buf);
                }
                
                blockStart = 0;
                blockEnd = 0;
            }
            return;
            
         case DIK_V:
            char buf[SimpleText::MAX_STRING_LENGTH + 1];
            
            //delete anything hilited
            if (blockEnd > 0)
            {
                //save the current state
                saveUndoState();
                
                strcpy(buf, &text[blockEnd]);
                cursorPos = blockStart;
                strcpy(&text[blockStart], buf);
                blockStart = 0;
                blockEnd = 0;
            }
      
            HGLOBAL   hglb; 
            LPTSTR    lptstr; 
            if (!IsClipboardFormatAvailable(CF_TEXT)) 
                return; 
            if (! OpenClipboard(getCanvas()->getHandle()))
                return; 
     
            hglb = GetClipboardData(CF_TEXT); 
            if (hglb != NULL) 
            { 
                lptstr = (char*)GlobalLock(hglb); 
                if (lptstr != NULL) 
                { 
                    int pasteLen = strlen(lptstr);
                    if ((stringLen + pasteLen) > maxStrLen)
                    {
                        pasteLen = maxStrLen - stringLen;
                    }
                                             
                    if (cursorPos == stringLen)
                    {
                        strncpy(&text[cursorPos], lptstr, pasteLen);
                        text[cursorPos + pasteLen] = '\0';
                    }
                    else
                    {
                        strcpy(buf, &text[cursorPos]);
                        strncpy(&text[cursorPos],lptstr, pasteLen);
                        strcpy(&text[cursorPos + pasteLen], buf);
                    }
                    cursorPos += pasteLen;
                    GlobalUnlock(hglb); 
                } 

            } 
            CloseClipboard();
            return; 
        
         case DIK_U:
            if (! dragHit)
            {
                char buf[SimpleText::MAX_STRING_LENGTH + 1];
                int tempBlockStart;
                int tempBlockEnd;
                int tempCursorPos;
                
                //save the current
                strcpy(buf, text);
                tempBlockStart = blockStart;
                tempBlockEnd = blockEnd;
                tempCursorPos = cursorPos;
                
                //restore the prev
                strcpy(text, undoText);
                blockStart = undoBlockStart;
                blockEnd = undoBlockEnd;
                cursorPos = undoCursorPos;
                
                //update the undo
                strcpy(undoText, buf);
                undoBlockStart = tempBlockStart;
                undoBlockEnd = tempBlockEnd;
                undoCursorPos = tempCursorPos;
                
                return;
             }
                
         case DIK_DELETE:
         case DIK_BACK:
            //save the current state
            saveUndoState();
            
            //delete everything in the field
            text[0] = '\0';
            cursorPos = 0;
            blockStart = 0;
            blockEnd = 0;
            return;
      } //switch
   }
   else
   {
      switch(event.diKeyCode)
      {
		 case DIK_LEFT:
            blockStart = 0;
            blockEnd = 0;
            if (cursorPos > 0)
            {
                cursorPos--;
            }
            return;
            
		 case DIK_RIGHT:
            blockStart = 0;
            blockEnd = 0;
            if (cursorPos < stringLen)
            {
                cursorPos++;
            }
            return;
                     
         case DIK_BACK:
            if (blockEnd > 0)
            {
                char buf[SimpleText::MAX_STRING_LENGTH + 1];
                strcpy(buf, &text[blockEnd]);
                cursorPos = blockStart;
                strcpy(&text[blockStart], buf);
                blockStart = 0;
                blockEnd = 0;
            }
            else if (cursorPos > 0)
            {
                char buf[SimpleText::MAX_STRING_LENGTH + 1];
                strcpy(buf, &text[cursorPos]);
                cursorPos--;
                strcpy(&text[cursorPos], buf);
            }
            return;
            
         case DIK_DELETE:
            //save the current state
            saveUndoState();
                
            if (blockEnd > 0)
            {
                char buf[SimpleText::MAX_STRING_LENGTH + 1];
                strcpy(buf, &text[blockEnd]);
                cursorPos = blockStart;
                strcpy(&text[blockStart], buf);
                blockStart = 0;
                blockEnd = 0;
            }
            else if (cursorPos < stringLen)
            {
                char buf[SimpleText::MAX_STRING_LENGTH + 1];
                strcpy(buf, &text[cursorPos + 1]);
                strcpy(&text[cursorPos], buf);
            }
            return;
         
         case DIK_INSERT:
            insertOn = !insertOn;
            return;
         
         case DIK_HOME:
            blockStart = 0;
            blockEnd = 0;
            cursorPos = 0;
            return;
            
         case DIK_END:
            blockStart = 0;
            blockEnd = 0;
            cursorPos = stringLen;
            return;
            
         }
   }
   
   switch (event.diKeyCode)
   {
      case DIK_UP:
      case DIK_DOWN:
      case DIK_TAB:
      case DIK_ESCAPE:
         Parent::onKeyDown(event);
         return;
   }
   
   //if ((! mbNumbersOnly && isprint(event.ascii)) || (mbNumbersOnly && event.ascii >= '0' && mbNumbersOnly && event.ascii <= '9'))
   if (isprint(event.ascii))
   {
      //see if it's a number field
      if (mbNumbersOnly)
      {
         if (event.ascii == '-')
         {
            //a minus sign only exists at the beginning, and only a single minus sign
            if (cursorPos != 0) return;
            if (insertOn && (text[0] == '-')) return;
         }
         else if (event.ascii < '0' || event.ascii > '9')
         {
            return;
         }
      }
      
      //save the current state
      saveUndoState();
                
      //delete anything hilited
      if (blockEnd > 0)
      {
          char buf[SimpleText::MAX_STRING_LENGTH + 1];
          strcpy(buf, &text[blockEnd]);
          cursorPos = blockStart;
          strcpy(&text[blockStart], buf);
          blockStart = 0;
          blockEnd = 0;
      }
      
      if ((insertOn && (stringLen < maxStrLen)) ||
          ((! insertOn) && (cursorPos < maxStrLen)))
      {
         if (cursorPos == stringLen)
         {
            text[cursorPos++] = event.ascii;
            text[cursorPos] = '\0';
         }
         else
         {
            if (insertOn)
            {
                char buf[SimpleText::MAX_STRING_LENGTH + 1];
                strcpy(buf, &text[cursorPos]);
                text[cursorPos] = event.ascii;
                cursorPos++;
                strcpy(&text[cursorPos], buf);
            }
            else
            {
                text[cursorPos++] = event.ascii;
                if (cursorPos > stringLen)
                {
                   text[cursorPos] = '\0';
                }
            }
         }
      }
      return;
   }
}
Exemplo n.º 9
0
 foreach(lineItem *line, lineItems){
     saveUndoState();
     line->myOwner()->setColor(myLineColor);
 }