void LogfileReader::updateView() { // get maximum size of logfile to display qint64 pos = Q_INT64_C(1024) * sizeSpin->value(); getTextView()->clear(); QFile file(fileName); if(file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); stream.setAutoDetectUnicode(true); // Set file pointer to <pos> bytes from the end if(stream.device()->size() > pos) { stream.device()->seek(stream.device()->size() - pos); } // Skip first line, since it may be incomplete // NOTE: we always skip the first line(in the log), but the // first line is just a '\n', so it's ok stream.readLine(); QString str; while(!stream.atEnd()) { str = stream.readLine().toHtmlEscaped(); getTextView()->appendLog(str); } stream.setDevice(0); file.close(); } }
void ChatWindow::updateAppearance() { if (getTextView()) getTextView()->updateAppearance(); // The font size of the KTabWidget container may be inappropriately // small due to the "Tab bar" font size setting. setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); }
void ChatContainer::textEntered() { const QString &line = sterilizeUnicode(m_inputBar->toPlainText()); if (line.isEmpty()) { return; } const QString &cc = Preferences::self()->commandChar(); if (line.startsWith(cc)) { QString cmd = line.section(' ', 0, 0).toLower(); kDebug() << "cmd" << cmd; if (cmd == cc + "clear") { textView->clear(); } else if (cmd == cc + "me") { QString toSend = line.section(' ', 1); //kDebug() << "toSend" << toSend; if (toSend.isEmpty()) { getTextView()->appendServerMessage(i18n("Usage"), i18n("Usage: %1ME text", Preferences::self()->commandChar())); } else { m_chat->sendAction(toSend); appendAction(m_chat->ownNick(), toSend); } } else if (cmd == cc + "close") { closeYourself(false); } else { getTextView()->appendServerMessage(i18n("Error"), i18n("Unknown command.")); } } else { textPasted(line); } m_inputBar->clear(); }
LogfileReader::LogfileReader(QWidget* parent, const QString& log, const QString& caption) : ChatWindow(parent) { setType(ChatWindow::LogFileReader); setName(i18n("Logfile of %1", caption)); fileName = log; setSpacing(0); toolBar = new KToolBar(this, true, true); toolBar->setObjectName("logfile_toolbar"); toolBar->addAction(QIcon::fromTheme("document-save-as"), i18n("Save As..."), this, SLOT(saveLog())); toolBar->addAction(QIcon::fromTheme("view-refresh"), i18n("Reload"), this, SLOT(updateView())); toolBar->addAction(QIcon::fromTheme("edit-delete"), i18n("Clear Logfile"), this, SLOT(clearLog())); toolBar->addWidget(new QLabel(i18n("Show last:"),toolBar)); sizeSpin = new QSpinBox(toolBar); sizeSpin->setMinimum(10); sizeSpin->setMaximum(1000); sizeSpin->setSingleStep(10); sizeSpin->setObjectName("logfile_size_spinbox"); sizeSpin->setWhatsThis(i18n("Use this box to set the maximum size of the log file. This setting does not take effect until you restart Konversation. Each log file may have a separate setting.")); sizeSpin->setValue(Preferences::self()->logfileBufferSize()); sizeSpin->setSuffix(i18n(" KB")); sizeSpin->installEventFilter(this); toolBar->addWidget(sizeSpin); connect(sizeSpin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &LogfileReader::storeBufferSize); IRCViewBox* ircBox = new IRCViewBox(this); setTextView(ircBox->ircView()); getTextView()->setWhatsThis(i18n("The messages in the log file are displayed here. The oldest messages are at the top and the most recent are at the bottom.")); updateView(); ircBox->ircView()->setFocusPolicy(Qt::StrongFocus); setFocusPolicy(Qt::StrongFocus); setFocusProxy(ircBox->ircView()); updateAppearance(); connect(getTextView(), SIGNAL(gotFocus()), getTextView(), SLOT(setFocus())); }
void ChatContainer::textPasted(const QString &text) { if (text.isEmpty()) { return; } const QStringList lines = sterilizeUnicode(text.split('\n', QString::SkipEmptyParts)); foreach (const QString &line, lines) { m_chat->sendText(line); getTextView()->append(m_chat->ownNick(), line); }
void ScrolledFileView::drawLeftMargin(cairo_t *cr) { GtkTextView *textView = getTextView(); DebuggerLocation dbgLoc = mDebugger.getStoppedLocation(); int marginWindowHeight = mLeftMargin.getMarginHeight(textView); std::vector<LineInfo> linesInfo = getLinesInfo(textView, marginWindowHeight); int lineHeight = linesInfo[1].yPos - linesInfo[0].yPos; DebuggerLocation thisFileLoc(getFilename()); int full = lineHeight*.8; int half = full/2; for(auto const & lineInfo : linesInfo) { int yPos; thisFileLoc.setLine(lineInfo.lineNum); gtk_text_view_buffer_to_window_coords (textView, GTK_TEXT_WINDOW_LEFT, 0, lineInfo.yPos, NULL, &yPos); mLeftMargin.drawMarginLineNum(textView, cr, lineInfo.lineNum, yPos); int centerY = yPos + lineHeight/2; if(mDebugger.getBreakpoints().anyLocationsMatch(thisFileLoc)) { cairo_set_source_rgb(cr, 128/255.0, 128/255.0, 0/255.0); cairo_arc(cr, half+1, centerY, half, 0, 2*M_PI); cairo_fill(cr); } if(dbgLoc == thisFileLoc) { cairo_set_source_rgb(cr, 0/255.0, 0/255.0, 255.0/255.0); cairo_move_to(cr, 0, centerY); cairo_line_to(cr, full, centerY); cairo_move_to(cr, full, centerY); cairo_line_to(cr, half, centerY-half); cairo_move_to(cr, full, centerY); cairo_line_to(cr, half, centerY+half); cairo_stroke(cr); } } mLeftMargin.drawMarginLine(textView, cr); cairo_fill(cr); // g_object_unref (G_OBJECT (layout)); }
void ScrolledFileView::drawRightMargin(cairo_t *cr) { GtkTextView *textView = getTextView(); GdkWindow *window = gtk_text_view_get_window(textView, GTK_TEXT_WINDOW_WIDGET); int textWindowHeight; gdk_window_get_geometry(window, NULL, NULL, NULL, &textWindowHeight); GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW( gtk_widget_get_parent(GTK_WIDGET(textView))); GtkAdjustment *adjust = gtk_scrolled_window_get_hadjustment(scrolledWindow); int scrollAdjust = (int)gtk_adjustment_get_value(adjust); // cairo_text_extents_t extents; // cairo_text_extents(cr, "5555555555", &extents); cairo_set_source_rgb(cr, 128/255.0, 128/255.0, 128/255.0); cairo_rectangle(cr, (mLeftMargin.getMarginWidth() + (mLeftMargin.getPixPerChar() * 80)) - scrollAdjust, 0, mLeftMargin.getMarginLineWidth(), textWindowHeight); cairo_fill(cr); }
void LogfileReader::childAdjustFocus() { getTextView()->setFocus(); }
QColor ChatWindow::highlightColor() { return getTextView()->highlightColor(); }
void ChatWindow::setLogfileName(const QString& name) { // Only change name of logfile if the window was new. if(firstLog) { if (getTextView()) getTextView()->setContextMenuOptions(IrcContextMenus::ShowLogAction, true); // status panels get special treatment here, since they have no server at the beginning if (getType() == Status || getType() == DccChat) { logName = name + ".log"; } else if (m_server) { // make sure that no path delimiters are in the name logName = QString(m_server->getDisplayName().toLower()).append('_').append(name).append(".log").replace('/','_'); } // load backlog to show if(Preferences::self()->showBacklog()) { // "cd" into log path or create path, if it's not there cdIntoLogPath(); // Show last log lines. This idea was stole ... um ... inspired by PMP :) // Don't do this for the server status windows, though if((getType() != Status) && logfile.open(QIODevice::ReadOnly)) { qint64 filePosition; QString backlogLine; QTextStream backlog(&logfile); backlog.setCodec(QTextCodec::codecForName("UTF-8")); backlog.setAutoDetectUnicode(true); QStringList firstColumns; QStringList messages; int offset = 0; qint64 lastPacketHeadPosition = backlog.device()->size(); const unsigned int packetSize = 4096; while(messages.count() < Preferences::self()->backlogLines() && backlog.device()->size() > packetSize * offset) { QStringList firstColumnsInPacket; QStringList messagesInPacket; // packetSize * offset < size <= packetSize * ( offset + 1 ) // Check if the log is bigger than packetSize * ( offset + 1 ) if(backlog.device()->size() > packetSize * ( offset + 1 )) { // Set file pointer to the packet size above the offset backlog.seek(backlog.device()->size() - packetSize * ( offset + 1 )); // Skip first line, since it may be incomplete backlog.readLine(); } else { // Set file pointer to the head // Qt 4.5 Doc: Note that when using a QTextStream on a // QFile, calling reset() on the QFile will not have the // expected result because QTextStream buffers the file. // Use the QTextStream::seek() function instead. // backlog.device()->reset(); backlog.seek( 0 ); } // remember actual file position to check for deadlocks filePosition = backlog.pos(); qint64 currentPacketHeadPosition = filePosition; // Loop until end of file reached while(!backlog.atEnd() && filePosition < lastPacketHeadPosition) { backlogLine = backlog.readLine(); // check for deadlocks if(backlog.pos() == filePosition) { backlog.seek(filePosition + 1); } // if a tab character is present in the line, meaning it is a valid chatline if (backlogLine.contains('\t')) { // extract first column from log QString backlogFirst = backlogLine.left(backlogLine.indexOf('\t')); // cut first column from line backlogLine = backlogLine.mid(backlogLine.indexOf('\t') + 1); // Logfile is in utf8 so we don't need to do encoding stuff here // append backlog with time and first column to text view firstColumnsInPacket << backlogFirst; messagesInPacket << backlogLine; } // remember actual file position to check for deadlocks filePosition = backlog.pos(); } // while // remember the position not to read the same lines again lastPacketHeadPosition = currentPacketHeadPosition; ++offset; firstColumns = firstColumnsInPacket + firstColumns; messages = messagesInPacket + messages; } backlog.setDevice(0); logfile.close(); // trim int surplus = messages.count() - Preferences::self()->backlogLines(); // "surplus" can be a minus value. (when the backlog is too short) if(surplus > 0) { for(int i = 0 ; i < surplus ; ++i) { firstColumns.pop_front(); messages.pop_front(); } } QStringList::Iterator itFirstColumn = firstColumns.begin(); QStringList::Iterator itMessage = messages.begin(); for( ; itFirstColumn != firstColumns.end() ; ++itFirstColumn, ++itMessage ) appendBacklogMessage(*itFirstColumn, *itMessage); } } // if(Preferences::showBacklog()) } }