void TEditor::doSearchReplace() { int i; do { i = cmCancel; if( search(findStr, editorFlags) == False ) { if( (editorFlags & (efReplaceAll | efDoReplace)) != (efReplaceAll | efDoReplace) ) editorDialog( edSearchFailed ); } else if( (editorFlags & efDoReplace) != 0 ) { i = cmYes; if( (editorFlags & efPromptOnReplace) != 0 ) { TPoint c = makeGlobal( cursor ); i = editorDialog( edReplacePrompt, &c ); } if( i == cmYes ) { lock(); insertText( replaceStr, strlen(replaceStr), False); trackCursor(False); unlock(); } } } while( i != cmCancel && (editorFlags & efReplaceAll) != 0 ); }
Boolean TEditor::search( const char *findStr, ushort opts ) { ushort pos = curPtr; ushort i; do { if( (opts & efCaseSensitive) != 0 ) i = scan( &buffer[bufPtr(pos)], bufLen - pos, findStr); else i = iScan( &buffer[bufPtr(pos)], bufLen - pos, findStr); if( i != sfSearchFailed ) { i += pos; if( (opts & efWholeWordsOnly) == 0 || !( ( i != 0 && isWordChar(bufChar(i - 1)) != 0 ) || ( i + strlen(findStr) != bufLen && isWordChar(bufChar(i + strlen(findStr))) ) )) { lock(); setSelect(i, i + strlen(findStr), False); trackCursor(Boolean(!cursorVisible())); unlock(); return True; } else pos = i + 1; } } while( i != sfSearchFailed ); return False; }
void *TFileEditor::read( ipstream& is ) { TEditor::read( is ); is.readString( fileName, sizeof( fileName ) ); if( isValid ) { isValid = loadFile(); size_t sStart, sEnd, curs; is >> sStart >> sEnd >> curs; if( isValid && sEnd <= bufLen ) { setSelect( sStart, sEnd, Boolean(curs == sStart) ); trackCursor( True ); } } return this; }
void TEditor::handleEvent( TEvent& event ) { TView::handleEvent( event ); convertEvent( event ); Boolean centerCursor = Boolean(!cursorVisible()); uchar selectMode = 0; if( selecting == True || (getShiftState() & 0x03) != 0 ) selectMode = smExtend; switch( event.what ) { case evMouseDown: if( event.mouse.doubleClick == True ) selectMode |= smDouble; do { lock(); if( event.what == evMouseAuto ) { TPoint mouse = makeLocal( event.mouse.where ); TPoint d = delta; if( mouse.x < 0 ) d.x--; if( mouse.x >= size.x ) d.x++; if( mouse.y < 0 ) d.y--; if( mouse.y >= size.y ) d.y++; scrollTo(d.x, d.y); } setCurPtr(getMousePtr(event.mouse.where), selectMode); selectMode |= smExtend; unlock(); } while( mouseEvent(event, evMouseMove + evMouseAuto) ); break; case evKeyDown: if( event.keyDown.charScan.charCode == 9 || ( event.keyDown.charScan.charCode >= 32 && event.keyDown.charScan.charCode < 255 ) ) { lock(); if( overwrite == True && hasSelection() == False ) if( curPtr != lineEnd(curPtr) ) selEnd = nextChar(curPtr); insertText( &event.keyDown.charScan.charCode, 1, False); trackCursor(centerCursor); unlock(); } else return; break; case evCommand: switch( event.message.command ) { case cmFind: find(); break; case cmReplace: replace(); break; case cmSearchAgain: doSearchReplace(); break; default: lock(); switch( event.message.command ) { case cmCut: clipCut(); break; case cmCopy: clipCopy(); // hideSelect(); // JS 12.4.94 break; case cmPaste: clipPaste(); break; case cmUndo: undo(); break; case cmClear: deleteSelect(); break; case cmCharLeft: setCurPtr(prevChar(curPtr), selectMode); break; case cmCharRight: setCurPtr(nextChar(curPtr), selectMode); break; case cmWordLeft: setCurPtr(prevWord(curPtr), selectMode); break; case cmWordRight: setCurPtr(nextWord(curPtr), selectMode); break; case cmLineStart: setCurPtr(lineStart(curPtr), selectMode); break; case cmLineEnd: setCurPtr(lineEnd(curPtr), selectMode); break; case cmLineUp: setCurPtr(lineMove(curPtr, -1), selectMode); break; case cmLineDown: setCurPtr(lineMove(curPtr, 1), selectMode); break; case cmPageUp: setCurPtr(lineMove(curPtr, -(size.y-1)), selectMode); break; case cmPageDown: setCurPtr(lineMove(curPtr, size.y-1), selectMode); break; case cmTextStart: setCurPtr(0, selectMode); break; case cmTextEnd: setCurPtr(bufLen, selectMode); break; case cmNewLine: newLine(); break; case cmBackSpace: deleteRange(prevChar(curPtr), curPtr, True); break; case cmDelChar: deleteRange(curPtr, nextChar(curPtr), True); break; case cmDelWord: deleteRange(curPtr, nextWord(curPtr), False); break; case cmDelStart: deleteRange(lineStart(curPtr), curPtr, False); break; case cmDelEnd: deleteRange(curPtr, lineEnd(curPtr), False); break; case cmDelLine: deleteRange(lineStart(curPtr), nextLine(curPtr), False); break; case cmInsMode: toggleInsMode(); break; case cmStartSelect: startSelect(); break; case cmHideSelect: hideSelect(); break; case cmIndentMode: autoIndent = Boolean(!autoIndent); break; default: unlock(); return; } trackCursor(centerCursor); unlock(); break; } case evBroadcast: switch( event.message.command ) { case cmScrollBarChanged: checkScrollBar( event, hScrollBar, delta.x ); checkScrollBar( event, vScrollBar, delta.y ); break; default: return; } } clearEvent(event); }
rmsMonitor::rmsMonitor (NV_INT32 *argc, NV_CHAR **argv, QWidget * parent): QMainWindow (parent, 0) { extern char *optarg; lock_track = NVFalse; QResource::registerResource ("/icons.rcc"); // Have to set the focus policy or keypress events don't work properly at first in Focus Follows Mouse mode setFocusPolicy (Qt::WheelFocus); setFocus (Qt::ActiveWindowFocusReason); // Set the main icon setWindowIcon (QIcon (":/icons/charts_monitor.png")); kill_switch = ANCILLARY_FORCE_EXIT; NV_INT32 option_index = 0; while (NVTrue) { static struct option long_options[] = {{"shared_memory_key", required_argument, 0, 0}, {"kill_switch", required_argument, 0, 0}, {0, no_argument, 0, 0}}; NV_CHAR c = (NV_CHAR) getopt_long (*argc, argv, "o", long_options, &option_index); if (c == -1) break; switch (c) { case 0: switch (option_index) { case 0: sscanf (optarg, "%d", &key); break; case 1: sscanf (optarg, "%d", &kill_switch); break; default: NV_CHAR tmp; sscanf (optarg, "%1c", &tmp); ac[option_index] = (NV_U_INT32) tmp; break; } break; } } if (!envin ()) { // Set the geometry from defaults since we didn't get any from the saved settings. this->resize (324, 400); this->move (0, 0); } setWindowTitle (QString (VERSION)); /******************************************* IMPORTANT NOTE ABOUT SHARED MEMORY **************************************** \ This is a little note about the use of shared memory within the Area-Based Editor (ABE) programs. If you read the Qt documentation (or anyone else's documentation) about the use of shared memory they will say "Dear [insert name of omnipotent being of your choice here], whatever you do, always lock shared memory when you use it!". The reason they say this is that access to shared memory is not atomic. That is, reading shared memory and then writing to it is not a single operation. An example of why this might be important - two programs are running, the first checks a value in shared memory, sees that it is a zero. The second program checks the same location and sees that it is a zero. These two programs have different actions they must perform depending on the value of that particular location in shared memory. Now the first program writes a one to that location which was supposed to tell the second program to do something but the second program thinks it's a zero. The second program doesn't do what it's supposed to do and it writes a two to that location. The two will tell the first program to do something. Obviously this could be a problem. In real life, this almost never occurs. Also, if you write your program properly you can make sure this doesn't happen. In ABE we almost never lock shared memory because something much worse than two programs getting out of sync can occur. If we start a program and it locks shared memory and then dies, all the other programs will be locked up. When you look through the ABE code you'll see that we very rarely lock shared memory, and then only for very short periods of time. This is by design. \******************************************* IMPORTANT NOTE ABOUT SHARED MEMORY ****************************************/ // Get the shared memory area. If it doesn't exist, quit. It should have already been created // by pfmView or geoSwath. QString skey; skey.sprintf ("%d_abe", key); abeShare = new QSharedMemory (skey); if (!abeShare->attach (QSharedMemory::ReadWrite)) { fprintf (stderr, "\n\nError retrieving shared memory segment in %s.\n\n", argv[0]); exit (-1); } abe_share = (ABE_SHARE *) abeShare->data (); // Open all the PFM structures that are being viewed in pfmEdit/pfmView num_pfms = abe_share->pfm_count; for (NV_INT32 pfm = 0 ; pfm < num_pfms ; pfm++) { open_args[pfm] = abe_share->open_args[pfm]; if ((pfm_handle[pfm] = open_existing_pfm_file (&open_args[pfm])) < 0) { QMessageBox::warning (this, tr ("Open PFM Structure"), tr ("The file ") + QDir::toNativeSeparators (QString (abe_share->open_args[pfm].list_path)) + tr (" is not a PFM handle or list file or there was an error reading the file.") + tr (" The error message returned was:\n\n") + QString (pfm_error_str (pfm_error))); } } QFrame *frame = new QFrame (this, 0); setCentralWidget (frame); QVBoxLayout *vBox = new QVBoxLayout (); vBox->setSpacing(0); frame->setLayout (vBox); listBox = new QTextEdit (this); listBox->setAutoFillBackground (TRUE); listBoxPalette.setColor (QPalette::Normal, QPalette::Base, bg_color); listBoxPalette.setColor (QPalette::Normal, QPalette::Window, bg_color); listBoxPalette.setColor (QPalette::Inactive, QPalette::Base, bg_color); listBoxPalette.setColor (QPalette::Inactive, QPalette::Window, bg_color); listBox->setPalette (listBoxPalette); listBox->setReadOnly (TRUE); vBox->addWidget (listBox); // Setup the file menu. QAction *fileQuitAction = new QAction (tr ("&Quit"), this); fileQuitAction->setStatusTip (tr ("Exit from application")); connect (fileQuitAction, SIGNAL (triggered ()), this, SLOT (slotQuit ())); QAction *filePrefsAction= new QAction (tr ("&Prefs"), this); filePrefsAction->setStatusTip (tr ("Set Preferences")); connect (filePrefsAction, SIGNAL (triggered ()), this, SLOT (slotPrefs ())); QMenu *fileMenu = menuBar ()->addMenu (tr ("&File")); fileMenu->addAction (filePrefsAction); fileMenu->addSeparator (); fileMenu->addAction (fileQuitAction); // Setup the help menu. I like leaving the About Qt in since this is // a really nice package - and it's open source. QAction *aboutAct = new QAction (tr ("&About"), this); aboutAct->setShortcut (tr ("Ctrl+A")); aboutAct->setStatusTip (tr ("Information about rmsMonitor")); connect (aboutAct, SIGNAL (triggered ()), this, SLOT (about ())); QAction *aboutQtAct = new QAction (tr ("About&Qt"), this); aboutQtAct->setShortcut (tr ("Ctrl+Q")); aboutQtAct->setStatusTip (tr ("Information about Qt")); connect (aboutQtAct, SIGNAL (triggered ()), this, SLOT (aboutQt ())); QAction *whatThisAct = QWhatsThis::createAction (this); QMenu *helpMenu = menuBar ()->addMenu (tr ("&Help")); helpMenu->addAction (aboutAct); helpMenu->addSeparator (); helpMenu->addAction (aboutQtAct); helpMenu->addAction (whatThisAct); // Setup the tracking timer QTimer *track = new QTimer (this); connect (track, SIGNAL (timeout ()), this, SLOT (trackCursor ())); track->start (10); }
waveWaterfall::waveWaterfall (NV_INT32 *argc, NV_CHAR **argv, QWidget * parent): QMainWindow (parent, 0) { extern char *optarg; filError = NULL; lock_track = NVFalse; QResource::registerResource ("/icons.rcc"); // Have to set the focus policy or keypress events don't work properly at first in Focus Follows Mouse mode setFocusPolicy (Qt::WheelFocus); wave_type = PMT; kill_switch = ANCILLARY_FORCE_EXIT; NV_INT32 option_index = 0; while (NVTrue) { static struct option long_options[] = {{"shared_memory_key", required_argument, 0, 0}, {"kill_switch", required_argument, 0, 0}, {0, no_argument, 0, 0}}; NV_CHAR c = (NV_CHAR) getopt_long (*argc, argv, "ap", long_options, &option_index); if (c == -1) break; switch (c) { case 0: switch (option_index) { case 0: sscanf (optarg, "%d", &key); break; case 1: sscanf (optarg, "%d", &kill_switch); break; } break; case 'a': wave_type = APD; break; case 'p': wave_type = PMT; break; } } if (!key) { fprintf (stderr, "\n\n--shared_memory_key argument not present on command line. Terminating!\n\n"); exit (-1); } // This is the "tools" toolbar. We have to do this here so that we can restore the toolbar location(s). QToolBar *tools = addToolBar (tr ("Tools")); tools->setObjectName (tr ("waveWaterfall main toolbar")); QString cap; if (wave_type == APD) { // Set the main icon setWindowIcon (QIcon (":/icons/wave_waterfall_apd.png")); cap.sprintf ("waveWaterfall (APD) : %s", VERSION); } else { // Set the main icon setWindowIcon (QIcon (":/icons/wave_waterfall_pmt.png")); cap.sprintf ("waveWaterfall (PMT) : %s", VERSION); } setWindowTitle (cap); /******************************************* IMPORTANT NOTE ABOUT SHARED MEMORY **************************************** \ This is a little note about the use of shared memory within the Area-Based Editor (ABE) programs. If you read the Qt documentation (or anyone else's documentation) about the use of shared memory they will say "Dear [insert name of omnipotent being of your choice here], whatever you do, always lock shared memory when you use it!". The reason they say this is that access to shared memory is not atomic. That is, reading shared memory and then writing to it is not a single operation. An example of why this might be important - two programs are running, the first checks a value in shared memory, sees that it is a zero. The second program checks the same location and sees that it is a zero. These two programs have different actions they must perform depending on the value of that particular location in shared memory. Now the first program writes a one to that location which was supposed to tell the second program to do something but the second program thinks it's a zero. The second program doesn't do what it's supposed to do and it writes a two to that location. The two will tell the first program to do something. Obviously this could be a problem. In real life, this almost never occurs. Also, if you write your program properly you can make sure this doesn't happen. In ABE we almost never lock shared memory because something much worse than two programs getting out of sync can occur. If we start a program and it locks shared memory and then dies, all the other programs will be locked up. When you look through the ABE code you'll see that we very rarely lock shared memory, and then only for very short periods of time. This is by design. \******************************************* IMPORTANT NOTE ABOUT SHARED MEMORY ****************************************/ // Get the shared memory area. If it doesn't exist, quit. It should have already been created // by pfmView or geoSwath. QString skey; skey.sprintf ("%d_abe", key); abeShare = new QSharedMemory (skey); if (!abeShare->attach (QSharedMemory::ReadWrite)) { fprintf (stderr, "\n\nError retrieving shared memory segment in %s.\n\n", argv[0]); exit (-1); } abe_share = (ABE_SHARE *) abeShare->data (); num_pfms = abe_share->pfm_count; for (NV_INT32 pfm = 0 ; pfm < num_pfms ; pfm++) { open_args[pfm] = abe_share->open_args[pfm]; if ((pfm_handle[pfm] = open_existing_pfm_file (&open_args[pfm])) < 0) { QMessageBox::warning (this, tr ("Open PFM Structure"), tr ("The file ") + QDir::toNativeSeparators (QString (abe_share->open_args[pfm].list_path)) + tr (" is not a PFM handle or list file or there was an error reading the file.") + tr (" The error message returned was:\n\n") + QString (pfm_error_str (pfm_error))); } } // Get the user's defaults envin (); // Set the window size and location from the defaults if (wave_type == APD) { this->resize (apd_width, apd_height); this->move (apd_window_x, apd_window_y); width = apd_width; height = apd_height; } else { this->resize (pmt_width, pmt_height); this->move (pmt_window_x, pmt_window_y); width = pmt_width; height = pmt_height; } adjusted_width = width - MAX_STACK_POINTS * WAVE_OFFSET; // Set the map values from the defaults mapdef.projection = NO_PROJECTION; mapdef.draw_width = width; mapdef.draw_height = height; mapdef.overlap_percent = 5; mapdef.grid_inc_x = 0.0; mapdef.grid_inc_y = 0.0; mapdef.coasts = NVFalse; mapdef.landmask = NVFalse; mapdef.border = 0; mapdef.coast_color = Qt::white; mapdef.grid_color = Qt::white; mapdef.background_color = backgroundColor; mapdef.initial_bounds.min_x = 0; mapdef.initial_bounds.min_y = 0; mapdef.initial_bounds.max_x = 500; mapdef.initial_bounds.max_y = 2048; QFrame *frame = new QFrame (this, 0); setCentralWidget (frame); // Make the map. map = new nvMap (this, &mapdef); map->setWhatsThis (mapText); // Connect to the signals from the map class. connect (map, SIGNAL (mousePressSignal (QMouseEvent *, NV_FLOAT64, NV_FLOAT64)), this, SLOT (slotMousePress (QMouseEvent *, NV_FLOAT64, NV_FLOAT64))); connect (map, SIGNAL (mouseMoveSignal (QMouseEvent *, NV_FLOAT64, NV_FLOAT64)), this, SLOT (slotMouseMove (QMouseEvent *, NV_FLOAT64, NV_FLOAT64))); connect (map, SIGNAL (resizeSignal (QResizeEvent *)), this, SLOT (slotResize (QResizeEvent *))); connect (map, SIGNAL (postRedrawSignal (NVMAP_DEF)), this, SLOT (slotPlotWaves (NVMAP_DEF))); // Layouts, what fun! QVBoxLayout *vBox = new QVBoxLayout (frame); vBox->addWidget (map); for (NV_INT32 i = 0 ; i < MAX_STACK_POINTS ; i++) { statusBar[i] = new QStatusBar (frame); statusBar[i]->setSizeGripEnabled (FALSE); statusBar[i]->show (); vBox->addWidget (statusBar[i]); dateLabel[i] = new QLabel ("0000-00-00 (000) 00:00:00.00", this); dateLabel[i]->setAlignment (Qt::AlignCenter); dateLabel[i]->setMinimumSize (dateLabel[i]->sizeHint ()); dateLabel[i]->setWhatsThis (dateLabelText); dateLabel[i]->setToolTip (tr ("Date and time")); dateLabel[i]->setAutoFillBackground (TRUE); dateLabelPalette[i] = dateLabel[i]->palette (); lineLabel[i] = new QLabel ("Line 000-0", this); lineLabel[i]->setAlignment (Qt::AlignCenter); lineLabel[i]->setMinimumSize (lineLabel[i]->sizeHint ()); lineLabel[i]->setWhatsThis (lineLabelText); lineLabel[i]->setToolTip (tr ("Line number")); lineLabel[i]->setAutoFillBackground (TRUE); lineLabelPalette[i] = lineLabel[i]->palette (); distLabel[i] = new QLabel ("000.00", this); distLabel[i]->setAlignment (Qt::AlignCenter); distLabel[i]->setMinimumSize (distLabel[i]->sizeHint ()); distLabel[i]->setWhatsThis (distLabelText); distLabel[i]->setToolTip (tr ("Distance in meters from selected points")); distLabel[i]->setAutoFillBackground (TRUE); distLabelPalette[i] = distLabel[i]->palette (); statusBar[i]->addWidget (dateLabel[i], 1); statusBar[i]->addWidget (lineLabel[i]); statusBar[i]->addWidget (distLabel[i]); } // Button, button, who's got the buttons? bQuit = new QToolButton (this); bQuit->setIcon (QIcon (":/icons/quit.xpm")); bQuit->setToolTip (tr ("Quit")); bQuit->setWhatsThis (quitText); connect (bQuit, SIGNAL (clicked ()), this, SLOT (slotQuit ())); tools->addWidget (bQuit); bMode = new QToolButton (this); if (wave_line_mode) { bMode->setIcon (QIcon (":/icons/mode_line.xpm")); } else { bMode->setIcon (QIcon (":/icons/mode_dot.xpm")); } bMode->setToolTip (tr ("Wave drawing mode toggle")); bMode->setWhatsThis (modeText); bMode->setCheckable (TRUE); bMode->setChecked (wave_line_mode); connect (bMode, SIGNAL (toggled (bool)), this, SLOT (slotMode (bool))); tools->addWidget (bMode); bPrefs = new QToolButton (this); bPrefs->setIcon (QIcon (":/icons/prefs.xpm")); bPrefs->setToolTip (tr ("Change application preferences")); bPrefs->setWhatsThis (prefsText); connect (bPrefs, SIGNAL (clicked ()), this, SLOT (slotPrefs ())); tools->addWidget (bPrefs); tools->addSeparator (); tools->addSeparator (); QAction *bHelp = QWhatsThis::createAction (this); bHelp->setIcon (QIcon (":/icons/contextHelp.xpm")); tools->addAction (bHelp); // Setup the file menu. QAction *fileQuitAction = new QAction (tr ("&Quit"), this); fileQuitAction->setShortcut (tr ("Ctrl+Q")); fileQuitAction->setStatusTip (tr ("Exit from application")); connect (fileQuitAction, SIGNAL (triggered ()), this, SLOT (slotQuit ())); QMenu *fileMenu = menuBar ()->addMenu (tr ("&File")); fileMenu->addAction (fileQuitAction); // Setup the help menu. QAction *aboutAct = new QAction (tr ("&About"), this); aboutAct->setShortcut (tr ("Ctrl+A")); aboutAct->setStatusTip (tr ("Information about waveWaterfall")); connect (aboutAct, SIGNAL (triggered ()), this, SLOT (about ())); QAction *acknowledgements = new QAction (tr ("A&cknowledgements"), this); acknowledgements->setShortcut (tr ("Ctrl+c")); acknowledgements->setStatusTip (tr ("Information about supporting libraries")); connect (acknowledgements, SIGNAL (triggered ()), this, SLOT (slotAcknowledgements ())); QAction *aboutQtAct = new QAction (tr ("About&Qt"), this); aboutQtAct->setShortcut (tr ("Ctrl+Q")); aboutQtAct->setStatusTip (tr ("Information about Qt")); connect (aboutQtAct, SIGNAL (triggered ()), this, SLOT (aboutQt ())); QMenu *helpMenu = menuBar ()->addMenu (tr ("&Help")); helpMenu->addAction (aboutAct); helpMenu->addSeparator (); helpMenu->addAction (acknowledgements); helpMenu->addAction (aboutQtAct); map->setCursor (Qt::ArrowCursor); map->enableSignals (); QTimer *track = new QTimer (this); connect (track, SIGNAL (timeout ()), this, SLOT (trackCursor ())); track->start (10); }