void
GMFilterNameTable::NewFilter()
{
	if (!itsConditionTable->OKToSwitch() || !itsActionTable->OKToSwitch())
		{
		return;
		}

	GMFilter* filter	= new GMFilter();
	assert(filter != NULL);

	itsFilters->Append(filter);

	JString nickname	= "filter" + JString(itsFilters->GetElementCount());
	filter->SetNickname(nickname);

	AppendRows(1, itsRowHeight);
	itsConditionTable->SetFilter(filter);
	itsActionTable->SetFilter(filter);

	GetTableSelection().ClearSelection();
	GetTableSelection().SelectCell(GetRowCount(), 1);

	AdjustButtons();
}
void
GLFitDescriptionList::HandleMouseDown
	(
	const JPoint& 			pt,
	const JXMouseButton 	button,
	const JSize 			clickCount,
	const JXButtonStates&	buttonStates,
	const JXKeyModifiers&	modifiers
	)
{
	JPoint cell;
	if (button == kJXLeftButton && GetCell(pt, &cell))
		{
		if (GetTableSelection().IsSelected(cell) && clickCount == 2)
			{
			Broadcast(FitInitiated(cell.y));
			}
		else if (!GetTableSelection().IsSelected(cell) && clickCount == 1)
			{
			SelectSingleCell(cell);
			Broadcast(FitSelected(cell.y));
			}
		}
	else
		{
		ScrollForWheel(button, modifiers);
		}
}
void
SelectionTable::HandleTableMenu
	(
	const JIndex index
	)
{
	// A menu item from the Table menu was selected.

	// Was it the Insert command?
	if (index == kInsertCmd)
		{
		// Get the selection object that JTable owns.
		JTableSelection& selection = GetTableSelection();

		// Since we disable the Insert command if there is more than
		// one cell selected or if none are selected, we know that
		// one cell is selected. We assert that only one cell is
		// selected.
		JPoint cell;

		// This finds the first selected cell, which in our case is
		// the only selected cell.
		const JBoolean ok = selection.GetFirstSelectedCell(&cell);
		assert(ok);

		// The default value is inserted before the selected cell.
		itsData->InsertElementAtIndex(cell.y, kDefInsertValue);
		}

	// Was it the Remove command?
	else if (index == kRemoveCmd)
		{
		// Get the selection object that JTable owns.
		JTableSelection& selection = GetTableSelection();

		// Create an iterator to iterate over each selected item.
		JTableSelectionIterator iter(&selection);

		// Loop through each selected cell.
		JPoint cell;
		while (iter.Next(&cell))
			{

			// Remove the element corresponding to the cell selected.
			// The table will automatically adjust itself in the
			// Receive function.
			itsData->RemoveElement(cell.y);
			}
		}

	// Was it the Quit command?
	else if (index == kQuitCmd)
		{
		// Get the application object (from jXGlobals.h) and call Quit 
		// to exit the program.
		JXGetApplication()->Quit();
		}
}
void
SVNListBase::GetSelectedFiles
	(
	JPtrArray<JString>*	fullNameList,
	const JBoolean		includeDeleted
	)
{
	fullNameList->CleanOut();
	fullNameList->SetCleanUpAction(JPtrArrayT::kDeleteAll);

	JTableSelection& s = GetTableSelection();
	JTableSelectionIterator iter(&s);
	JString name, fullName;
	JPoint cell;
	const JString& basePath = GetPath();
	while (iter.Next(&cell))
		{
		const JString* line   = itsLineList->NthElement(cell.y);
		name                  = ExtractRelativePath(*line);
		const JBoolean exists = JConvertToAbsolutePath(name, basePath, &fullName);
		if (exists || includeDeleted)
			{
			fullNameList->Append(fullName);
			}
		}
}
void
SVNListBase::HandleEditMenu
	(
	const JIndex index
	)
{
	const JString* id;
	if (!itsEditMenu->GetItemID(index, &id))
		{
		return;
		}

	if (*id == kJXCopyAction)
		{
		CopySelectedItems(kJFalse);
		}
	else if (*id == kSVNCopyFullPathAction)
		{
		CopySelectedItems(kJTrue);
		}
	else if (*id == kJXSelectAllAction)
		{
		(GetTableSelection()).SelectAll();
		}
}
void
SVNListBase::ReceiveMessageLine()
{
	assert( itsMessageLink != NULL );

	JString line;
	const JBoolean ok = itsMessageLink->GetNextMessage(&line);
	assert( ok );

	if (!ShouldDisplayLine(&line))
		{
		return;
		}

	const JFontStyle red(kJTrue, kJFalse, 0, kJFalse, (GetColormap())->GetRedColor());
	const JFontStyle blue = (GetColormap())->GetBlueColor();
	const JFontStyle strike(kJFalse, kJFalse, 0, kJTrue);

	JString* temp = new JString(line);
	assert( temp != NULL );

	JIndex i;
	itsLineList->InsertSorted(temp, kJTrue, &i);
	StyleLine(i, line, red, blue, strike);

	JString relPath = ExtractRelativePath(line);
	JIndex j;
	if (itsSavedSelection->SearchSorted(&relPath, JOrderedSetT::kAnyMatch, &j))
		{
		(GetTableSelection()).SelectRow(i);
		}
}
void
SVNListBase::RefreshContent()
{
	if (itsProcess != NULL)
		{
		JProcess* p = itsProcess;
		itsProcess  = NULL;

		p->Kill();
		delete p;

		DeleteLinks();
		}
	else
		{
		itsSavedSelection->CleanOut();
		JTableSelection& s = GetTableSelection();
		JTableSelectionIterator iter(&s);
		JPoint cell;
		while (iter.Next(&cell))
			{
			const JString* line = itsLineList->NthElement(cell.y);
			itsSavedSelection->InsertSorted(new JString(ExtractRelativePath(*line)));
			}
		}

	itsDisplayState = SaveDisplayState();
	itsLineList->CleanOut();

	int outFD, errFD;
	JError err = JNoError();
	if ((GetDirector())->HasPath())
		{
		err = JProcess::Create(&itsProcess, GetPath(), itsCmd,
							   kJIgnoreConnection, NULL,
							   kJCreatePipe, &outFD,
							   kJCreatePipe, &errFD);
		}
	else	// working with URL
		{
		err = JProcess::Create(&itsProcess, itsCmd,
							   kJIgnoreConnection, NULL,
							   kJCreatePipe, &outFD,
							   kJCreatePipe, &errFD);
		}

	if (err.OK())
		{
		itsProcess->ShouldDeleteWhenFinished();
		ListenTo(itsProcess);
		(GetDirector())->RegisterActionProcess(this, itsProcess, itsRefreshRepoFlag,
											   itsRefreshStatusFlag, itsReloadOpenFilesFlag);

		SetConnection(outFD, errFD);
		}
	else
		{
		err.ReportIfError();
		}
}
JBoolean
SVNPropertiesList::SchedulePropertiesForRemove()
{
	JTableSelection& s = GetTableSelection();
	JTableSelectionIterator iter(&s);
	JPoint cell;
	JString cmd, prop, file = JPrepArgForExec(itsFullName);
	JSubstitute subst;
	while (iter.Next(&cell))
		{
		const JString* line = (GetStringList()).NthElement(cell.y);

		prop = JPrepArgForExec(*line);

		cmd = kPropRemoveCmd;
		subst.DefineVariable("prop_name", prop);
		subst.DefineVariable("file_name", file);
		subst.Substitute(&cmd);

		itsRemovePropertyCmdList->Append(cmd);
		}

	RemoveNextProperty();
	return kJTrue;
}
void
SVNPropertiesList::CopySelectedItems
	(
	const JBoolean fullPath
	)
{
	JTableSelection& s = GetTableSelection();
	if (!s.HasSelection())
		{
		return;
		}

	JPtrArray<JString> list(JPtrArrayT::kDeleteAll);
	JTableSelectionIterator iter(&s);
	JPoint cell;
	while (iter.Next(&cell))
		{
		list.Append(*((GetStringList()).NthElement(cell.y)));
		}

	JXTextSelection* data = new JXTextSelection(GetDisplay(), list);
	assert( data != NULL );

	(GetSelectionManager())->SetData(kJXClipboardName, data);
}
void
JXTreeListWidget::HandlePrepareForNodeMove()
{
	// save selected nodes

	itsReselectNodeList->RemoveAll();

	JTableSelectionIterator iter(&(GetTableSelection()));
	JPoint cell;
	while (iter.Next(&cell))
		{
		JTreeNode* node = itsTreeList->GetNode(cell.y);
		if (!itsReselectNodeList->Includes(node))
			{
			itsReselectNodeList->Append(node);
			}
		}

	// save scroll position

	std::ostringstream data;
	WriteScrollSetup(data);

	assert( itsSavedScrollSetup == NULL );
	itsSavedScrollSetup = new JString(data.str());
	assert( itsSavedScrollSetup != NULL );
}
void
JX2DCurveNameList::HandleKeyPress
	(
	const int				key,
	const JXKeyModifiers&	modifiers
	)
{
	JPoint cell;
	JTableSelection& s = GetTableSelection();
	const JBoolean ok  = s.GetFirstSelectedCell(&cell);
	assert( ok );

	if (key == kJUpArrow)
		{
		cell.y--;
		if (CellValid(cell))
			{
			BeginEditing(cell);
			}
		}
	else if (key == kJDownArrow)
		{
		cell.y++;
		if (CellValid(cell))
			{
			BeginEditing(cell);
			}
		}

	else
		{
		JXEditTable::HandleKeyPress(key, modifiers);
		}
}
void
JXFSBindingTable::RemovePattern()
{
	JPoint cell;
	if ((GetTableSelection()).GetFirstSelectedCell(&cell))
		{
		if ((itsBindingList->GetBinding(cell.y))->IsSystemBinding())
			{
			JGetUserNotification()->ReportError(JGetString(kCantRemoveSystemBindingID));
			}
		else
			{
			CancelEditing();
			if (itsBindingList->DeleteBinding(cell.y))
				{
				RemoveRow(cell.y);
				}
			else
				{
				TableRefreshRow(cell.y);
				GetWindow()->Update();
				(JGetUserNotification())->DisplayMessage(JGetString(kReplacedBySystemID));
				}
			UpdateButtons();
			Broadcast(DataChanged());
			}
		}
}
void
CBSymbolTable::CopySelectedSymbolNames()
	const
{
	itsKeyBuffer.Clear();

	const JTableSelection& s = GetTableSelection();
	if (s.HasSelection())
		{
		JPtrArray<JString> list(JPtrArrayT::kForgetAll);

		CBLanguage lang;
		CBSymbolList::Type type;

		JTableSelectionIterator iter(&s);
		JPoint cell;
		while (iter.Next(&cell))
			{
			const JString& name = itsSymbolList->GetSymbol(CellToSymbolIndex(cell), &lang, &type);
			list.Append(const_cast<JString*>(&name));
			}

		JXTextSelection* data = new JXTextSelection(GetDisplay(), list);
		assert( data != NULL );

		(GetSelectionManager())->SetData(kJXClipboardName, data);
		}
}
void
CMArray2DTable::HandleKeyPress
	(
	const int				key,
	const JXKeyModifiers&	modifiers
	)
{
	if (key == kJReturnKey)
		{
		JPoint cell;
		if (!IsEditing() && (GetTableSelection()).GetSingleSelectedCell(&cell))
			{
			BeginEditing(cell);
			}
		else
			{
			EndEditing();
			}
		}

	else if (!IsEditing() && HandleSelectionKeyPress(key, modifiers))
		{
		// work has been done
		}

	else
		{
		JXStringTable::HandleKeyPress(key, modifiers);
		}
}
void
CBMacroSetTable::SwitchDisplay()
{
	if (itsMacroIndex > 0)
		{
		const CBPrefsManager::MacroSetInfo info = itsMacroList->GetElement(itsMacroIndex);
		itsActionTable->GetData(info.action);
		itsMacroTable->GetData(info.macro);
		}

	JPoint cell;
	if ((GetTableSelection()).GetFirstSelectedCell(&cell))
		{
		itsMacroIndex = cell.y;

		const CBPrefsManager::MacroSetInfo info = itsMacroList->GetElement(itsMacroIndex);
		itsActionTable->SetData(*(info.action));
		itsMacroTable->SetData(*(info.macro));

		itsRemoveRowButton->Activate();
		}
	else
		{
		itsMacroIndex = 0;

		itsActionTable->ClearData();
		itsMacroTable->ClearData();

		itsRemoveRowButton->Deactivate();
		}
}
void
GMAccountList::HandleMouseDown
	(
	const JPoint&			pt,
	const JXMouseButton	button,
	const JSize			clickCount,
	const JXButtonStates&	buttonStates,
	const JXKeyModifiers&	modifiers
	)
{
	JPoint cell;
	if (button == kJXLeftButton && clickCount == 1 &&
		GetCell(pt, &cell))
		{
		JTableSelection& s = GetTableSelection();
		if (!s.IsSelected(cell) && itsDialog->OKToSwitchAccounts())
			{
			s.ClearSelection();
			s.SelectRow(cell.y);
			Broadcast(NameSelected(cell.y));
			BeginEditing(cell);
			}
		else if (s.IsSelected(cell) && !IsEditing())
			{
			BeginEditing(cell);
			}
		}
	else if (button > kJXRightButton)
		{
		ScrollForWheel(button, modifiers);
		}
}
void
CBCommandTable::HandleOptionsMenu
	(
	const JIndex index
	)
{
	JPoint cell;
	const JBoolean ok = (GetTableSelection()).GetFirstSelectedCell(&cell);
	assert( ok );

	CBCommandManager::CmdInfo info = itsCmdList->GetElement(cell.y);
	if (index == kIsMakeCmd)
		{
		info.isMake = !info.isMake;
		if (info.isMake)
			{
			info.saveAll   = kJTrue;
			info.useWindow = kJTrue;
			}
		}
	else if (index == kIsCVSCmd)
		{
		info.isVCS = !info.isVCS;
		if (info.isVCS)
			{
			info.saveAll = kJTrue;
			}
		}
	else if (index == kSaveAllCmd)
		{
		info.saveAll = !info.saveAll;
		}
	else if (index == kOneAtATimeCmd)
		{
		info.oneAtATime = !info.oneAtATime;
		}
	else if (index == kUseWindowCmd)
		{
		info.useWindow = !info.useWindow;
		if (!info.useWindow)
			{
			info.raiseWindowWhenStart = kJFalse;
			}
		}
	else if (index == kRaisedWhenStartCmd)
		{
		info.raiseWindowWhenStart = !info.raiseWindowWhenStart;
		}
	else if (index == kBeepWhenFinishedCmd)
		{
		info.beepWhenFinished = !info.beepWhenFinished;
		}
	else if (index == kShowSeparatorCmd)
		{
		info.separator = !info.separator;
		}

	TableRefreshRow(cell.y);
	itsCmdList->SetElement(cell.y, info);
}
void
CBMacroSetTable::Receive
	(
	JBroadcaster*	sender,
	const Message&	message
	)
{
	if (sender == itsAddRowButton && message.Is(JXButton::kPushed))
		{
		AddRow();
		}
	else if (sender == itsRemoveRowButton && message.Is(JXButton::kPushed))
		{
		RemoveRow();
		}

	else
		{
		if (sender == &(GetTableSelection()))
			{
			SwitchDisplay();
			}

		JXStringTable::Receive(sender, message);
		}
}
void
JXTreeListWidget::CloseSelectedNodes
	(
	const JBoolean closeSiblings,
	const JBoolean closeDescendants
	)
{
	JTableSelectionIterator iter(&(GetTableSelection()));
	JPoint cell;
	while (iter.Next(&cell))
		{
		if (closeSiblings)
			{
			itsTreeList->CloseSiblings(cell.y);
			}
		if (closeDescendants)
			{
			itsTreeList->CloseDescendants(cell.y);
			}
		if (!closeSiblings && !closeDescendants)
			{
			itsTreeList->Close(cell.y);
			}
		}
}
void
GMFilterNameTable::HandleDNDDrop
	(
	const JPoint&		pt,
	const JArray<Atom>& typeList,
	const Atom			action,
	const Time			time,
	const JXWidget*	source
	)
{
	JIndex dropIndex	= itsCurrentDNDIndex;
	if (dropIndex == 0)
		{
		dropIndex		= GetRowCount() + 1;
		}
	JPoint cell;
	if (GetTableSelection().GetFirstSelectedCell(&cell))
		{
		if (cell.y == (JCoordinate)itsCurrentDNDIndex ||
			cell.y == (JCoordinate)itsCurrentDNDIndex + 1)
			{
			return;
			}
		GMFilter* filter	= itsFilters->NthElement(cell.y);
		itsFilters->Remove(filter);
		JIndex newIndex		= dropIndex;
		if (cell.y < (JCoordinate)newIndex)
			{
			newIndex--;
			}
		itsFilters->InsertAtIndex(newIndex, filter);
		SelectFilter(newIndex);
		}
	HandleDNDLeave();
}
void
JXTreeListWidget::OpenSelectedNodes
	(
	const JBoolean openSiblings,
	const JBoolean openDescendants
	)
{
	JTableSelectionIterator iter(&(GetTableSelection()));
	iter.MoveTo(kJIteratorStartAtEnd, 0,0);
	JPoint cell, lastCell;
	while (iter.Prev(&cell))
		{
		if (openSiblings)
			{
			itsTreeList->OpenSiblings(cell.y);
			}
		if (openDescendants)
			{
			itsTreeList->OpenDescendants(cell.y, itsMaxOpenDepth);
			}
		if (!openSiblings && !openDescendants)
			{
			itsTreeList->Open(cell.y);
			}

		lastCell = cell;
		}

	if (RowIndexValid(lastCell.y) && !openSiblings)
		{
		ScrollToShowChildren(lastCell.y);
		}
}
void
JXTreeListWidget::SelectNodes
	(
	const JPtrArray<JTreeNode>& list
	)
{
	JTableSelection& s = GetTableSelection();

	const JSize count = list.GetElementCount();
	for (JIndex i=1; i<=count; i++)
		{
		const JTreeNode* node = list.NthElement(i);
		JIndex index;
		if (itsTreeList->FindNode(node, &index))
			{
			const JPoint cell(itsNodeColIndex, index);
			s.SelectCell(cell);

			if (!s.HasAnchor())
				{
				s.SetAnchor(cell);
				}
			s.SetBoat(cell);
			}
		}
}
void
CBSymbolTable::GetFileNamesForSelection
	(
	JPtrArray<JString>*	fileNameList,
	JArray<JIndex>*		lineIndexList
	)
	const
{
	itsKeyBuffer.Clear();

	const JTableSelection& s = GetTableSelection();
	if (s.HasSelection())
		{
		JTableSelectionIterator iter(&s);
		JPoint cell;
		while (iter.Next(&cell))
			{
			const JIndex symbolIndex = CellToSymbolIndex(cell);
			JIndex lineIndex;
			const JString& fileName =
				itsSymbolList->GetFile(symbolIndex, &lineIndex);

			fileNameList->Append(fileName);
			lineIndexList->AppendElement(lineIndex);
			}
		}
}
JXInputField*
CBCommandTable::CreateXInputField
	(
	const JPoint&		cell,
	const JCoordinate	x,
	const JCoordinate	y,
	const JCoordinate	w,
	const JCoordinate	h
	)
{
	assert( itsTextInput == NULL );

	JTableSelection& s = GetTableSelection();
	s.ClearSelection();
	s.SelectCell(cell);

	if (cell.x == kPathColumn)
		{
		CBCommandPathInput* pathInput =
			new CBCommandPathInput(this, kFixedLeft, kFixedTop, x,y, w,h);
		pathInput->SetBasePath(itsBasePath);
		pathInput->ShouldAllowInvalidPath();
		itsTextInput = pathInput;
		}
	else
		{
		itsTextInput = new JXInputField(this, kFixedLeft, kFixedTop, x,y, w,h);
		}
	assert( itsTextInput != NULL );

	const CBCommandManager::CmdInfo info = itsCmdList->GetElement(cell.y);
	const JString* text = NULL;
	if (cell.x == kMenuTextColumn)
		{
		text = info.menuText;
		}
	else if (cell.x == kMenuShortcutColumn)
		{
		text = info.menuShortcut;
		}
	else if (cell.x == kScriptNameColumn)
		{
		text = info.name;
		}
	else if (cell.x == kCommandColumn)
		{
		text = info.cmd;
		}
	else if (cell.x == kPathColumn)
		{
		text = info.path;
		}
	assert( text != NULL );

	itsTextInput->SetText(*text);
	itsTextInput->SetFont(itsFontName, itsFontSize);
	return itsTextInput;
}
void
GMAccountList::GMAccountListX()
{
	AppendCols(1, kDefColWidth);
	const JSize count	= itsAccountInfo->GetElementCount();
	AppendRows(count, itsLineHeight);
	GetTableSelection().SelectRow(1);
	WantInput(kJFalse);
}
void
JXFSBindingTable::UpdateTypeMenu()
{
	JPoint cell;
	const JBoolean ok = (GetTableSelection()).GetFirstSelectedCell(&cell);
	assert( ok );

	const JFSBinding* b = itsBindingList->GetBinding(cell.y);
	itsTypeMenu->CheckItem(kCmdTypeToMenuIndex[ b->GetCommandType() ]);
}
void
SelectionTable::HandleMouseDown
	(
	const JPoint& 			pt, 
	const JXMouseButton 	button,
	const JSize 			clickCount,
	const JXButtonStates& 	buttonStates,
	const JXKeyModifiers& 	modifiers
	)
{
	if (button == kJXLeftButton)
		{
		// We first need to find out which cell contains this point.
		JPoint cell;
		if (GetCell(pt, &cell))
			{
			// We clicked in the table.

			// Get the selection object that JTable owns.
			JTableSelection& selection = GetTableSelection();

			// Select the cell that the user clicked on.
			selection.SelectCell(cell);
			}
		else
			{
			// We clicked the mouse outside of the table.

			// Get the selection object that JTable owns.
			JTableSelection& selection = GetTableSelection();

			// Clear the selection.
			selection.ClearSelection();
			}
		}

	// Let the base class handle the wheel mouse.
	else
		{
		ScrollForWheel(button, modifiers);
		}
}
void
CBCommandTable::DuplicateCommand()
{
	JPoint cell;
	if ((GetTableSelection()).GetFirstSelectedCell(&cell) && EndEditing())
		{
		itsCmdList->AppendElement((itsCmdList->GetElement(cell.y)).Copy());
		AppendRows(1);
		BeginEditing(JPoint(kCommandColumn, itsCmdList->GetElementCount()));
		}
}
void
GMFilterNameTable::AdjustButtons()
{
	if (GetRowCount() == 0 || !GetTableSelection().HasSelection())
		{
		itsRemoveButton->Deactivate();
		}
	else
		{
		itsRemoveButton->Activate();
		}
}
void
CMArray2DTable::UpdateEditMenu()
{
	JXTEBase* te = GetEditMenuHandler();

	JIndex index;
	if ((GetTableSelection()).HasSelection() &&
		te->EditMenuCmdToIndex(JTextEditor::kCopyCmd, &index))
		{
		itsEditMenu->EnableItem(index);
		}
}